123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942 |
- /* -*- mode: asm -*-
- **
- ** head.S -- This file contains the initial boot code for the
- ** Linux/68k kernel.
- **
- ** Copyright 1993 by Hamish Macdonald
- **
- ** 68040 fixes by Michael Rausch
- ** 68060 fixes by Roman Hodek
- ** MMU cleanup by Randy Thelen
- ** Final MMU cleanup by Roman Zippel
- **
- ** Atari support by Andreas Schwab, using ideas of Robert de Vries
- ** and Bjoern Brauel
- ** VME Support by Richard Hirst
- **
- ** 94/11/14 Andreas Schwab: put kernel at PAGESIZE
- ** 94/11/18 Andreas Schwab: remove identity mapping of STRAM for Atari
- ** ++ Bjoern & Roman: ATARI-68040 support for the Medusa
- ** 95/11/18 Richard Hirst: Added MVME166 support
- ** 96/04/26 Guenther Kelleter: fixed identity mapping for Falcon with
- ** Magnum- and FX-alternate ram
- ** 98/04/25 Phil Blundell: added HP300 support
- ** 1998/08/30 David Kilzer: Added support for font_desc structures
- ** for linux-2.1.115
- ** 9/02/11 Richard Zidlicky: added Q40 support (initial vesion 99/01/01)
- ** 2004/05/13 Kars de Jong: Finalised HP300 support
- **
- ** This file is subject to the terms and conditions of the GNU General Public
- ** License. See the file README.legal in the main directory of this archive
- ** for more details.
- **
- */
- /*
- * Linux startup code.
- *
- * At this point, the boot loader has:
- * Disabled interrupts
- * Disabled caches
- * Put us in supervisor state.
- *
- * The kernel setup code takes the following steps:
- * . Raise interrupt level
- * . Set up initial kernel memory mapping.
- * . This sets up a mapping of the 4M of memory the kernel is located in.
- * . It also does a mapping of any initial machine specific areas.
- * . Enable the MMU
- * . Enable cache memories
- * . Jump to kernel startup
- *
- * Much of the file restructuring was to accomplish:
- * 1) Remove register dependency through-out the file.
- * 2) Increase use of subroutines to perform functions
- * 3) Increase readability of the code
- *
- * Of course, readability is a subjective issue, so it will never be
- * argued that that goal was accomplished. It was merely a goal.
- * A key way to help make code more readable is to give good
- * documentation. So, the first thing you will find is exaustive
- * write-ups on the structure of the file, and the features of the
- * functional subroutines.
- *
- * General Structure:
- * ------------------
- * Without a doubt the single largest chunk of head.S is spent
- * mapping the kernel and I/O physical space into the logical range
- * for the kernel.
- * There are new subroutines and data structures to make MMU
- * support cleaner and easier to understand.
- * First, you will find a routine call "mmu_map" which maps
- * a logical to a physical region for some length given a cache
- * type on behalf of the caller. This routine makes writing the
- * actual per-machine specific code very simple.
- * A central part of the code, but not a subroutine in itself,
- * is the mmu_init code which is broken down into mapping the kernel
- * (the same for all machines) and mapping machine-specific I/O
- * regions.
- * Also, there will be a description of engaging the MMU and
- * caches.
- * You will notice that there is a chunk of code which
- * can emit the entire MMU mapping of the machine. This is present
- * only in debug modes and can be very helpful.
- * Further, there is a new console driver in head.S that is
- * also only engaged in debug mode. Currently, it's only supported
- * on the Macintosh class of machines. However, it is hoped that
- * others will plug-in support for specific machines.
- *
- * ######################################################################
- *
- * mmu_map
- * -------
- * mmu_map was written for two key reasons. First, it was clear
- * that it was very difficult to read the previous code for mapping
- * regions of memory. Second, the Macintosh required such extensive
- * memory allocations that it didn't make sense to propagate the
- * existing code any further.
- * mmu_map requires some parameters:
- *
- * mmu_map (logical, physical, length, cache_type)
- *
- * While this essentially describes the function in the abstract, you'll
- * find more indepth description of other parameters at the implementation site.
- *
- * mmu_get_root_table_entry
- * ------------------------
- * mmu_get_ptr_table_entry
- * -----------------------
- * mmu_get_page_table_entry
- * ------------------------
- *
- * These routines are used by other mmu routines to get a pointer into
- * a table, if necessary a new table is allocated. These routines are working
- * basically like pmd_alloc() and pte_alloc() in <asm/pgtable.h>. The root
- * table needs of course only to be allocated once in mmu_get_root_table_entry,
- * so that here also some mmu specific initialization is done. The second page
- * at the start of the kernel (the first page is unmapped later) is used for
- * the kernel_pg_dir. It must be at a position known at link time (as it's used
- * to initialize the init task struct) and since it needs special cache
- * settings, it's the easiest to use this page, the rest of the page is used
- * for further pointer tables.
- * mmu_get_page_table_entry allocates always a whole page for page tables, this
- * means 1024 pages and so 4MB of memory can be mapped. It doesn't make sense
- * to manage page tables in smaller pieces as nearly all mappings have that
- * size.
- *
- * ######################################################################
- *
- *
- * ######################################################################
- *
- * mmu_engage
- * ----------
- * Thanks to a small helping routine enabling the mmu got quite simple
- * and there is only one way left. mmu_engage makes a complete a new mapping
- * that only includes the absolute necessary to be able to jump to the final
- * postion and to restore the original mapping.
- * As this code doesn't need a transparent translation register anymore this
- * means all registers are free to be used by machines that needs them for
- * other purposes.
- *
- * ######################################################################
- *
- * mmu_print
- * ---------
- * This algorithm will print out the page tables of the system as
- * appropriate for an 030 or an 040. This is useful for debugging purposes
- * and as such is enclosed in #ifdef MMU_PRINT/#endif clauses.
- *
- * ######################################################################
- *
- * console_init
- * ------------
- * The console is also able to be turned off. The console in head.S
- * is specifically for debugging and can be very useful. It is surrounded by
- * #ifdef CONSOLE/#endif clauses so it doesn't have to ship in known-good
- * kernels. It's basic algorithm is to determine the size of the screen
- * (in height/width and bit depth) and then use that information for
- * displaying an 8x8 font or an 8x16 (widthxheight). I prefer the 8x8 for
- * debugging so I can see more good data. But it was trivial to add support
- * for both fonts, so I included it.
- * Also, the algorithm for plotting pixels is abstracted so that in
- * theory other platforms could add support for different kinds of frame
- * buffers. This could be very useful.
- *
- * console_put_penguin
- * -------------------
- * An important part of any Linux bring up is the penguin and there's
- * nothing like getting the Penguin on the screen! This algorithm will work
- * on any machine for which there is a console_plot_pixel.
- *
- * console_scroll
- * --------------
- * My hope is that the scroll algorithm does the right thing on the
- * various platforms, but it wouldn't be hard to add the test conditions
- * and new code if it doesn't.
- *
- * console_putc
- * -------------
- *
- * ######################################################################
- *
- * Register usage has greatly simplified within head.S. Every subroutine
- * saves and restores all registers that it modifies (except it returns a
- * value in there of course). So the only register that needs to be initialized
- * is the stack pointer.
- * All other init code and data is now placed in the init section, so it will
- * be automatically freed at the end of the kernel initialization.
- *
- * ######################################################################
- *
- * options
- * -------
- * There are many options available in a build of this file. I've
- * taken the time to describe them here to save you the time of searching
- * for them and trying to understand what they mean.
- *
- * CONFIG_xxx: These are the obvious machine configuration defines created
- * during configuration. These are defined in include/linux/autoconf.h.
- *
- * CONSOLE: There is support for head.S console in this file. This
- * console can talk to a Mac frame buffer, but could easily be extrapolated
- * to extend it to support other platforms.
- *
- * TEST_MMU: This is a test harness for running on any given machine but
- * getting an MMU dump for another class of machine. The classes of machines
- * that can be tested are any of the makes (Atari, Amiga, Mac, VME, etc.)
- * and any of the models (030, 040, 060, etc.).
- *
- * NOTE: TEST_MMU is NOT permanent! It is scheduled to be removed
- * When head.S boots on Atari, Amiga, Macintosh, and VME
- * machines. At that point the underlying logic will be
- * believed to be solid enough to be trusted, and TEST_MMU
- * can be dropped. Do note that that will clean up the
- * head.S code significantly as large blocks of #if/#else
- * clauses can be removed.
- *
- * MMU_NOCACHE_KERNEL: On the Macintosh platform there was an inquiry into
- * determing why devices don't appear to work. A test case was to remove
- * the cacheability of the kernel bits.
- *
- * MMU_PRINT: There is a routine built into head.S that can display the
- * MMU data structures. It outputs its result through the serial_putc
- * interface. So where ever that winds up driving data, that's where the
- * mmu struct will appear. On the Macintosh that's typically the console.
- *
- * SERIAL_DEBUG: There are a series of putc() macro statements
- * scattered through out the code to give progress of status to the
- * person sitting at the console. This constant determines whether those
- * are used.
- *
- * DEBUG: This is the standard DEBUG flag that can be set for building
- * the kernel. It has the effect adding additional tests into
- * the code.
- *
- * FONT_6x11:
- * FONT_8x8:
- * FONT_8x16:
- * In theory these could be determined at run time or handed
- * over by the booter. But, let's be real, it's a fine hard
- * coded value. (But, you will notice the code is run-time
- * flexible!) A pointer to the font's struct font_desc
- * is kept locally in Lconsole_font. It is used to determine
- * font size information dynamically.
- *
- * Atari constants:
- * USE_PRINTER: Use the printer port for serial debug.
- * USE_SCC_B: Use the SCC port A (Serial2) for serial debug.
- * USE_SCC_A: Use the SCC port B (Modem2) for serial debug.
- * USE_MFP: Use the ST-MFP port (Modem1) for serial debug.
- *
- * Macintosh constants:
- * MAC_SERIAL_DEBUG: Turns on serial debug output for the Macintosh.
- * MAC_USE_SCC_A: Use the SCC port A (modem) for serial debug.
- * MAC_USE_SCC_B: Use the SCC port B (printer) for serial debug (default).
- */
- #include <linux/config.h>
- #include <linux/linkage.h>
- #include <linux/init.h>
- #include <asm/bootinfo.h>
- #include <asm/setup.h>
- #include <asm/entry.h>
- #include <asm/pgtable.h>
- #include <asm/page.h>
- #include <asm/asm-offsets.h>
- #ifdef CONFIG_MAC
- #include <asm/machw.h>
- /*
- * Macintosh console support
- */
- #ifdef CONFIG_FRAMEBUFFER_CONSOLE
- #define CONSOLE
- #define CONSOLE_PENGUIN
- #endif
- /*
- * Macintosh serial debug support; outputs boot info to the printer
- * and/or modem serial ports
- */
- #undef MAC_SERIAL_DEBUG
- /*
- * Macintosh serial debug port selection; define one or both;
- * requires MAC_SERIAL_DEBUG to be defined
- */
- #define MAC_USE_SCC_A /* Macintosh modem serial port */
- #define MAC_USE_SCC_B /* Macintosh printer serial port */
- #endif /* CONFIG_MAC */
- #undef MMU_PRINT
- #undef MMU_NOCACHE_KERNEL
- #define SERIAL_DEBUG
- #undef DEBUG
- /*
- * For the head.S console, there are three supported fonts, 6x11, 8x16 and 8x8.
- * The 8x8 font is harder to read but fits more on the screen.
- */
- #define FONT_8x8 /* default */
- /* #define FONT_8x16 */ /* 2nd choice */
- /* #define FONT_6x11 */ /* 3rd choice */
- .globl kernel_pg_dir
- .globl availmem
- .globl m68k_pgtable_cachemode
- .globl m68k_supervisor_cachemode
- #ifdef CONFIG_MVME16x
- .globl mvme_bdid
- #endif
- #ifdef CONFIG_Q40
- .globl q40_mem_cptr
- #endif
- CPUTYPE_040 = 1 /* indicates an 040 */
- CPUTYPE_060 = 2 /* indicates an 060 */
- CPUTYPE_0460 = 3 /* if either above are set, this is set */
- CPUTYPE_020 = 4 /* indicates an 020 */
- /* Translation control register */
- TC_ENABLE = 0x8000
- TC_PAGE8K = 0x4000
- TC_PAGE4K = 0x0000
- /* Transparent translation registers */
- TTR_ENABLE = 0x8000 /* enable transparent translation */
- TTR_ANYMODE = 0x4000 /* user and kernel mode access */
- TTR_KERNELMODE = 0x2000 /* only kernel mode access */
- TTR_USERMODE = 0x0000 /* only user mode access */
- TTR_CI = 0x0400 /* inhibit cache */
- TTR_RW = 0x0200 /* read/write mode */
- TTR_RWM = 0x0100 /* read/write mask */
- TTR_FCB2 = 0x0040 /* function code base bit 2 */
- TTR_FCB1 = 0x0020 /* function code base bit 1 */
- TTR_FCB0 = 0x0010 /* function code base bit 0 */
- TTR_FCM2 = 0x0004 /* function code mask bit 2 */
- TTR_FCM1 = 0x0002 /* function code mask bit 1 */
- TTR_FCM0 = 0x0001 /* function code mask bit 0 */
- /* Cache Control registers */
- CC6_ENABLE_D = 0x80000000 /* enable data cache (680[46]0) */
- CC6_FREEZE_D = 0x40000000 /* freeze data cache (68060) */
- CC6_ENABLE_SB = 0x20000000 /* enable store buffer (68060) */
- CC6_PUSH_DPI = 0x10000000 /* disable CPUSH invalidation (68060) */
- CC6_HALF_D = 0x08000000 /* half-cache mode for data cache (68060) */
- CC6_ENABLE_B = 0x00800000 /* enable branch cache (68060) */
- CC6_CLRA_B = 0x00400000 /* clear all entries in branch cache (68060) */
- CC6_CLRU_B = 0x00200000 /* clear user entries in branch cache (68060) */
- CC6_ENABLE_I = 0x00008000 /* enable instruction cache (680[46]0) */
- CC6_FREEZE_I = 0x00004000 /* freeze instruction cache (68060) */
- CC6_HALF_I = 0x00002000 /* half-cache mode for instruction cache (68060) */
- CC3_ALLOC_WRITE = 0x00002000 /* write allocate mode(68030) */
- CC3_ENABLE_DB = 0x00001000 /* enable data burst (68030) */
- CC3_CLR_D = 0x00000800 /* clear data cache (68030) */
- CC3_CLRE_D = 0x00000400 /* clear entry in data cache (68030) */
- CC3_FREEZE_D = 0x00000200 /* freeze data cache (68030) */
- CC3_ENABLE_D = 0x00000100 /* enable data cache (68030) */
- CC3_ENABLE_IB = 0x00000010 /* enable instruction burst (68030) */
- CC3_CLR_I = 0x00000008 /* clear instruction cache (68030) */
- CC3_CLRE_I = 0x00000004 /* clear entry in instruction cache (68030) */
- CC3_FREEZE_I = 0x00000002 /* freeze instruction cache (68030) */
- CC3_ENABLE_I = 0x00000001 /* enable instruction cache (68030) */
- /* Miscellaneous definitions */
- PAGESIZE = 4096
- PAGESHIFT = 12
- ROOT_TABLE_SIZE = 128
- PTR_TABLE_SIZE = 128
- PAGE_TABLE_SIZE = 64
- ROOT_INDEX_SHIFT = 25
- PTR_INDEX_SHIFT = 18
- PAGE_INDEX_SHIFT = 12
- #ifdef DEBUG
- /* When debugging use readable names for labels */
- #ifdef __STDC__
- #define L(name) .head.S.##name
- #else
- #define L(name) .head.S./**/name
- #endif
- #else
- #ifdef __STDC__
- #define L(name) .L##name
- #else
- #define L(name) .L/**/name
- #endif
- #endif
- /* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
- #ifndef __INITDATA
- #define __INITDATA .data
- #define __FINIT .previous
- #endif
- /* Several macros to make the writing of subroutines easier:
- * - func_start marks the beginning of the routine which setups the frame
- * register and saves the registers, it also defines another macro
- * to automatically restore the registers again.
- * - func_return marks the end of the routine and simply calls the prepared
- * macro to restore registers and jump back to the caller.
- * - func_define generates another macro to automatically put arguments
- * onto the stack call the subroutine and cleanup the stack again.
- */
- /* Within subroutines these macros can be used to access the arguments
- * on the stack. With STACK some allocated memory on the stack can be
- * accessed and ARG0 points to the return address (used by mmu_engage).
- */
- #define STACK %a6@(stackstart)
- #define ARG0 %a6@(4)
- #define ARG1 %a6@(8)
- #define ARG2 %a6@(12)
- #define ARG3 %a6@(16)
- #define ARG4 %a6@(20)
- .macro func_start name,saveregs,stack=0
- L(\name):
- linkw %a6,#-\stack
- moveml \saveregs,%sp@-
- .set stackstart,-\stack
- .macro func_return_\name
- moveml %sp@+,\saveregs
- unlk %a6
- rts
- .endm
- .endm
- .macro func_return name
- func_return_\name
- .endm
- .macro func_call name
- jbsr L(\name)
- .endm
- .macro move_stack nr,arg1,arg2,arg3,arg4
- .if \nr
- move_stack "(\nr-1)",\arg2,\arg3,\arg4
- movel \arg1,%sp@-
- .endif
- .endm
- .macro func_define name,nr=0
- .macro \name arg1,arg2,arg3,arg4
- move_stack \nr,\arg1,\arg2,\arg3,\arg4
- func_call \name
- .if \nr
- lea %sp@(\nr*4),%sp
- .endif
- .endm
- .endm
- func_define mmu_map,4
- func_define mmu_map_tt,4
- func_define mmu_fixup_page_mmu_cache,1
- func_define mmu_temp_map,2
- func_define mmu_engage
- func_define mmu_get_root_table_entry,1
- func_define mmu_get_ptr_table_entry,2
- func_define mmu_get_page_table_entry,2
- func_define mmu_print
- func_define get_new_page
- #if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
- func_define set_leds
- #endif
- .macro mmu_map_eq arg1,arg2,arg3
- mmu_map \arg1,\arg1,\arg2,\arg3
- .endm
- .macro get_bi_record record
- pea \record
- func_call get_bi_record
- addql #4,%sp
- .endm
- func_define serial_putc,1
- func_define console_putc,1
- func_define console_init
- func_define console_put_stats
- func_define console_put_penguin
- func_define console_plot_pixel,3
- func_define console_scroll
- .macro putc ch
- #if defined(CONSOLE) || defined(SERIAL_DEBUG)
- pea \ch
- #endif
- #ifdef CONSOLE
- func_call console_putc
- #endif
- #ifdef SERIAL_DEBUG
- func_call serial_putc
- #endif
- #if defined(CONSOLE) || defined(SERIAL_DEBUG)
- addql #4,%sp
- #endif
- .endm
- .macro dputc ch
- #ifdef DEBUG
- putc \ch
- #endif
- .endm
- func_define putn,1
- .macro dputn nr
- #ifdef DEBUG
- putn \nr
- #endif
- .endm
- .macro puts string
- #if defined(CONSOLE) || defined(SERIAL_DEBUG)
- __INITDATA
- .Lstr\@:
- .string "\string"
- __FINIT
- pea %pc@(.Lstr\@)
- func_call puts
- addql #4,%sp
- #endif
- .endm
- .macro dputs string
- #ifdef DEBUG
- puts "\string"
- #endif
- .endm
- #define is_not_amiga(lab) cmpl &MACH_AMIGA,%pc@(m68k_machtype); jne lab
- #define is_not_atari(lab) cmpl &MACH_ATARI,%pc@(m68k_machtype); jne lab
- #define is_not_mac(lab) cmpl &MACH_MAC,%pc@(m68k_machtype); jne lab
- #define is_not_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jne lab
- #define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab
- #define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab
- #define is_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jeq lab
- #define is_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jeq lab
- #define is_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jeq lab
- #define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab
- #define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab
- #define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
- #define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
- #define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \
- jeq 42f; \
- cmpl &MACH_APOLLO,%pc@(m68k_machtype); \
- jne lab ;\
- 42:\
- #define is_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jne lab
- #define is_not_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jeq lab
- #define is_040(lab) btst &CPUTYPE_040,%pc@(L(cputype)+3); jne lab
- #define is_060(lab) btst &CPUTYPE_060,%pc@(L(cputype)+3); jne lab
- #define is_not_060(lab) btst &CPUTYPE_060,%pc@(L(cputype)+3); jeq lab
- #define is_020(lab) btst &CPUTYPE_020,%pc@(L(cputype)+3); jne lab
- #define is_not_020(lab) btst &CPUTYPE_020,%pc@(L(cputype)+3); jeq lab
- /* On the HP300 we use the on-board LEDs for debug output before
- the console is running. Writing a 1 bit turns the corresponding LED
- _off_ - on the 340 bit 7 is towards the back panel of the machine. */
- .macro leds mask
- #if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
- hasnt_leds(.Lled\@)
- pea \mask
- func_call set_leds
- addql #4,%sp
- .Lled\@:
- #endif
- .endm
- .text
- ENTRY(_stext)
- /*
- * Version numbers of the bootinfo interface
- * The area from _stext to _start will later be used as kernel pointer table
- */
- bras 1f /* Jump over bootinfo version numbers */
- .long BOOTINFOV_MAGIC
- .long MACH_AMIGA, AMIGA_BOOTI_VERSION
- .long MACH_ATARI, ATARI_BOOTI_VERSION
- .long MACH_MVME147, MVME147_BOOTI_VERSION
- .long MACH_MVME16x, MVME16x_BOOTI_VERSION
- .long MACH_BVME6000, BVME6000_BOOTI_VERSION
- .long MACH_MAC, MAC_BOOTI_VERSION
- .long MACH_Q40, Q40_BOOTI_VERSION
- .long MACH_HP300, HP300_BOOTI_VERSION
- .long 0
- 1: jra __start
- .equ kernel_pg_dir,_stext
- .equ .,_stext+PAGESIZE
- ENTRY(_start)
- jra __start
- __INIT
- ENTRY(__start)
- /*
- * Setup initial stack pointer
- */
- lea %pc@(_stext),%sp
- /*
- * Record the CPU and machine type.
- */
- get_bi_record BI_MACHTYPE
- lea %pc@(m68k_machtype),%a1
- movel %a0@,%a1@
- get_bi_record BI_FPUTYPE
- lea %pc@(m68k_fputype),%a1
- movel %a0@,%a1@
- get_bi_record BI_MMUTYPE
- lea %pc@(m68k_mmutype),%a1
- movel %a0@,%a1@
- get_bi_record BI_CPUTYPE
- lea %pc@(m68k_cputype),%a1
- movel %a0@,%a1@
- leds 0x1
- #ifdef CONFIG_MAC
- /*
- * For Macintosh, we need to determine the display parameters early (at least
- * while debugging it).
- */
- is_not_mac(L(test_notmac))
- get_bi_record BI_MAC_VADDR
- lea %pc@(L(mac_videobase)),%a1
- movel %a0@,%a1@
- get_bi_record BI_MAC_VDEPTH
- lea %pc@(L(mac_videodepth)),%a1
- movel %a0@,%a1@
- get_bi_record BI_MAC_VDIM
- lea %pc@(L(mac_dimensions)),%a1
- movel %a0@,%a1@
- get_bi_record BI_MAC_VROW
- lea %pc@(L(mac_rowbytes)),%a1
- movel %a0@,%a1@
- #ifdef MAC_SERIAL_DEBUG
- get_bi_record BI_MAC_SCCBASE
- lea %pc@(L(mac_sccbase)),%a1
- movel %a0@,%a1@
- #endif /* MAC_SERIAL_DEBUG */
- #if 0
- /*
- * Clear the screen
- */
- lea %pc@(L(mac_videobase)),%a0
- movel %a0@,%a1
- lea %pc@(L(mac_dimensions)),%a0
- movel %a0@,%d1
- swap %d1 /* #rows is high bytes */
- andl #0xFFFF,%d1 /* rows */
- subl #10,%d1
- lea %pc@(L(mac_rowbytes)),%a0
- loopy2:
- movel %a0@,%d0
- subql #1,%d0
- loopx2:
- moveb #0x55, %a1@+
- dbra %d0,loopx2
- dbra %d1,loopy2
- #endif
- L(test_notmac):
- #endif /* CONFIG_MAC */
- /*
- * There are ultimately two pieces of information we want for all kinds of
- * processors CpuType and CacheBits. The CPUTYPE was passed in from booter
- * and is converted here from a booter type definition to a separate bit
- * number which allows for the standard is_0x0 macro tests.
- */
- movel %pc@(m68k_cputype),%d0
- /*
- * Assume it's an 030
- */
- clrl %d1
- /*
- * Test the BootInfo cputype for 060
- */
- btst #CPUB_68060,%d0
- jeq 1f
- bset #CPUTYPE_060,%d1
- bset #CPUTYPE_0460,%d1
- jra 3f
- 1:
- /*
- * Test the BootInfo cputype for 040
- */
- btst #CPUB_68040,%d0
- jeq 2f
- bset #CPUTYPE_040,%d1
- bset #CPUTYPE_0460,%d1
- jra 3f
- 2:
- /*
- * Test the BootInfo cputype for 020
- */
- btst #CPUB_68020,%d0
- jeq 3f
- bset #CPUTYPE_020,%d1
- jra 3f
- 3:
- /*
- * Record the cpu type
- */
- lea %pc@(L(cputype)),%a0
- movel %d1,%a0@
- /*
- * NOTE:
- *
- * Now the macros are valid:
- * is_040_or_060
- * is_not_040_or_060
- * is_040
- * is_060
- * is_not_060
- */
- /*
- * Determine the cache mode for pages holding MMU tables
- * and for supervisor mode, unused for '020 and '030
- */
- clrl %d0
- clrl %d1
- is_not_040_or_060(L(save_cachetype))
- /*
- * '040 or '060
- * d1 := cacheable write-through
- * NOTE: The 68040 manual strongly recommends non-cached for MMU tables,
- * but we have been using write-through since at least 2.0.29 so I
- * guess it is OK.
- */
- #ifdef CONFIG_060_WRITETHROUGH
- /*
- * If this is a 68060 board using drivers with cache coherency
- * problems, then supervisor memory accesses need to be write-through
- * also; otherwise, we want copyback.
- */
- is_not_060(1f)
- movel #_PAGE_CACHE040W,%d0
- jra L(save_cachetype)
- #endif /* CONFIG_060_WRITETHROUGH */
- 1:
- movew #_PAGE_CACHE040,%d0
- movel #_PAGE_CACHE040W,%d1
- L(save_cachetype):
- /* Save cache mode for supervisor mode and page tables
- */
- lea %pc@(m68k_supervisor_cachemode),%a0
- movel %d0,%a0@
- lea %pc@(m68k_pgtable_cachemode),%a0
- movel %d1,%a0@
- /*
- * raise interrupt level
- */
- movew #0x2700,%sr
- /*
- If running on an Atari, determine the I/O base of the
- serial port and test if we are running on a Medusa or Hades.
- This test is necessary here, because on the Hades the serial
- port is only accessible in the high I/O memory area.
- The test whether it is a Medusa is done by writing to the byte at
- phys. 0x0. This should result in a bus error on all other machines.
- ...should, but doesn't. The Afterburner040 for the Falcon has the
- same behaviour (0x0..0x7 are no ROM shadow). So we have to do
- another test to distinguish Medusa and AB040. This is a
- read attempt for 0x00ff82fe phys. that should bus error on a Falcon
- (+AB040), but is in the range where the Medusa always asserts DTACK.
- The test for the Hades is done by reading address 0xb0000000. This
- should give a bus error on the Medusa.
- */
- #ifdef CONFIG_ATARI
- is_not_atari(L(notypetest))
- /* get special machine type (Medusa/Hades/AB40) */
- moveq #0,%d3 /* default if tag doesn't exist */
- get_bi_record BI_ATARI_MCH_TYPE
- tstl %d0
- jbmi 1f
- movel %a0@,%d3
- lea %pc@(atari_mch_type),%a0
- movel %d3,%a0@
- 1:
- /* On the Hades, the iobase must be set up before opening the
- * serial port. There are no I/O regs at 0x00ffxxxx at all. */
- moveq #0,%d0
- cmpl #ATARI_MACH_HADES,%d3
- jbne 1f
- movel #0xff000000,%d0 /* Hades I/O base addr: 0xff000000 */
- 1: lea %pc@(L(iobase)),%a0
- movel %d0,%a0@
- L(notypetest):
- #endif
- #ifdef CONFIG_VME
- is_mvme147(L(getvmetype))
- is_bvme6000(L(getvmetype))
- is_not_mvme16x(L(gvtdone))
- /* See if the loader has specified the BI_VME_TYPE tag. Recent
- * versions of VMELILO and TFTPLILO do this. We have to do this
- * early so we know how to handle console output. If the tag
- * doesn't exist then we use the Bug for output on MVME16x.
- */
- L(getvmetype):
- get_bi_record BI_VME_TYPE
- tstl %d0
- jbmi 1f
- movel %a0@,%d3
- lea %pc@(vme_brdtype),%a0
- movel %d3,%a0@
- 1:
- #ifdef CONFIG_MVME16x
- is_not_mvme16x(L(gvtdone))
- /* Need to get the BRD_ID info to differentiate between 162, 167,
- * etc. This is available as a BI_VME_BRDINFO tag with later
- * versions of VMELILO and TFTPLILO, otherwise we call the Bug.
- */
- get_bi_record BI_VME_BRDINFO
- tstl %d0
- jpl 1f
- /* Get pointer to board ID data from Bug */
- movel %d2,%sp@-
- trap #15
- .word 0x70 /* trap 0x70 - .BRD_ID */
- movel %sp@+,%a0
- 1:
- lea %pc@(mvme_bdid),%a1
- /* Structure is 32 bytes long */
- movel %a0@+,%a1@+
- movel %a0@+,%a1@+
- movel %a0@+,%a1@+
- movel %a0@+,%a1@+
- movel %a0@+,%a1@+
- movel %a0@+,%a1@+
- movel %a0@+,%a1@+
- movel %a0@+,%a1@+
- #endif
- L(gvtdone):
- #endif
- #ifdef CONFIG_HP300
- is_not_hp300(L(nothp))
- /* Get the address of the UART for serial debugging */
- get_bi_record BI_HP300_UART_ADDR
- tstl %d0
- jbmi 1f
- movel %a0@,%d3
- lea %pc@(L(uartbase)),%a0
- movel %d3,%a0@
- get_bi_record BI_HP300_UART_SCODE
- tstl %d0
- jbmi 1f
- movel %a0@,%d3
- lea %pc@(L(uart_scode)),%a0
- movel %d3,%a0@
- 1:
- L(nothp):
- #endif
- /*
- * Initialize serial port
- */
- jbsr L(serial_init)
- /*
- * Initialize console
- */
- #ifdef CONFIG_MAC
- is_not_mac(L(nocon))
- #ifdef CONSOLE
- console_init
- #ifdef CONSOLE_PENGUIN
- console_put_penguin
- #endif /* CONSOLE_PENGUIN */
- console_put_stats
- #endif /* CONSOLE */
- L(nocon):
- #endif /* CONFIG_MAC */
- putc '\n'
- putc 'A'
- leds 0x2
- dputn %pc@(L(cputype))
- dputn %pc@(m68k_supervisor_cachemode)
- dputn %pc@(m68k_pgtable_cachemode)
- dputc '\n'
- /*
- * Save physical start address of kernel
- */
- lea %pc@(L(phys_kernel_start)),%a0
- lea %pc@(_stext),%a1
- subl #_stext,%a1
- addl #PAGE_OFFSET,%a1
- movel %a1,%a0@
- putc 'B'
- leds 0x4
- /*
- * mmu_init
- *
- * This block of code does what's necessary to map in the various kinds
- * of machines for execution of Linux.
- * First map the first 4 MB of kernel code & data
- */
- mmu_map #PAGE_OFFSET,%pc@(L(phys_kernel_start)),#4*1024*1024,\
- %pc@(m68k_supervisor_cachemode)
- putc 'C'
- #ifdef CONFIG_AMIGA
- L(mmu_init_amiga):
- is_not_amiga(L(mmu_init_not_amiga))
- /*
- * mmu_init_amiga
- */
- putc 'D'
- is_not_040_or_060(1f)
- /*
- * 040: Map the 16Meg range physical 0x0 upto logical 0x8000.0000
- */
- mmu_map #0x80000000,#0,#0x01000000,#_PAGE_NOCACHE_S
- /*
- * Map the Zorro III I/O space with transparent translation
- * for frame buffer memory etc.
- */
- mmu_map_tt #1,#0x40000000,#0x20000000,#_PAGE_NOCACHE_S
- jbra L(mmu_init_done)
- 1:
- /*
- * 030: Map the 32Meg range physical 0x0 upto logical 0x8000.0000
- */
- mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
- mmu_map_tt #1,#0x40000000,#0x20000000,#_PAGE_NOCACHE030
- jbra L(mmu_init_done)
- L(mmu_init_not_amiga):
- #endif
- #ifdef CONFIG_ATARI
- L(mmu_init_atari):
- is_not_atari(L(mmu_init_not_atari))
- putc 'E'
- /* On the Atari, we map the I/O region (phys. 0x00ffxxxx) by mapping
- the last 16 MB of virtual address space to the first 16 MB (i.e.
- 0xffxxxxxx -> 0x00xxxxxx). For this, an additional pointer table is
- needed. I/O ranges are marked non-cachable.
- For the Medusa it is better to map the I/O region transparently
- (i.e. 0xffxxxxxx -> 0xffxxxxxx), because some I/O registers are
- accessible only in the high area.
- On the Hades all I/O registers are only accessible in the high
- area.
- */
- /* I/O base addr for non-Medusa, non-Hades: 0x00000000 */
- moveq #0,%d0
- movel %pc@(atari_mch_type),%d3
- cmpl #ATARI_MACH_MEDUSA,%d3
- jbeq 2f
- cmpl #ATARI_MACH_HADES,%d3
- jbne 1f
- 2: movel #0xff000000,%d0 /* Medusa/Hades base addr: 0xff000000 */
- 1: movel %d0,%d3
- is_040_or_060(L(spata68040))
- /* Map everything non-cacheable, though not all parts really
- * need to disable caches (crucial only for 0xff8000..0xffffff
- * (standard I/O) and 0xf00000..0xf3ffff (IDE)). The remainder
- * isn't really used, except for sometimes peeking into the
- * ROMs (mirror at phys. 0x0), so caching isn't necessary for
- * this. */
- mmu_map #0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE030
- jbra L(mmu_init_done)
- L(spata68040):
- mmu_map #0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE_S
- jbra L(mmu_init_done)
- L(mmu_init_not_atari):
- #endif
- #ifdef CONFIG_Q40
- is_not_q40(L(notq40))
- /*
- * add transparent mapping for 0xff00 0000 - 0xffff ffff
- * non-cached serialized etc..
- * this includes master chip, DAC, RTC and ISA ports
- * 0xfe000000-0xfeffffff is for screen and ROM
- */
- putc 'Q'
- mmu_map_tt #0,#0xfe000000,#0x01000000,#_PAGE_CACHE040W
- mmu_map_tt #1,#0xff000000,#0x01000000,#_PAGE_NOCACHE_S
- jbra L(mmu_init_done)
- L(notq40):
- #endif
- #ifdef CONFIG_HP300
- is_not_hp300(L(nothp300))
- /* On the HP300, we map the ROM, INTIO and DIO regions (phys. 0x00xxxxxx)
- * by mapping 32MB (on 020/030) or 16 MB (on 040) from 0xf0xxxxxx -> 0x00xxxxxx).
- * The ROM mapping is needed because the LEDs are mapped there too.
- */
- is_040(1f)
- /*
- * 030: Map the 32Meg range physical 0x0 upto logical 0xf000.0000
- */
- mmu_map #0xf0000000,#0,#0x02000000,#_PAGE_NOCACHE030
- jbra L(mmu_init_done)
- 1:
- /*
- * 040: Map the 16Meg range physical 0x0 upto logical 0xf000.0000
- */
- mmu_map #0xf0000000,#0,#0x01000000,#_PAGE_NOCACHE_S
- jbra L(mmu_init_done)
- L(nothp300):
- #endif /* CONFIG_HP300 */
- #ifdef CONFIG_MVME147
- is_not_mvme147(L(not147))
- /*
- * On MVME147 we have already created kernel page tables for
- * 4MB of RAM at address 0, so now need to do a transparent
- * mapping of the top of memory space. Make it 0.5GByte for now,
- * so we can access on-board i/o areas.
- */
- mmu_map_tt #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE030
- jbra L(mmu_init_done)
- L(not147):
- #endif /* CONFIG_MVME147 */
- #ifdef CONFIG_MVME16x
- is_not_mvme16x(L(not16x))
- /*
- * On MVME16x we have already created kernel page tables for
- * 4MB of RAM at address 0, so now need to do a transparent
- * mapping of the top of memory space. Make it 0.5GByte for now.
- * Supervisor only access, so transparent mapping doesn't
- * clash with User code virtual address space.
- * this covers IO devices, PROM and SRAM. The PROM and SRAM
- * mapping is needed to allow 167Bug to run.
- * IO is in the range 0xfff00000 to 0xfffeffff.
- * PROM is 0xff800000->0xffbfffff and SRAM is
- * 0xffe00000->0xffe1ffff.
- */
- mmu_map_tt #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
- jbra L(mmu_init_done)
- L(not16x):
- #endif /* CONFIG_MVME162 | CONFIG_MVME167 */
- #ifdef CONFIG_BVME6000
- is_not_bvme6000(L(not6000))
- /*
- * On BVME6000 we have already created kernel page tables for
- * 4MB of RAM at address 0, so now need to do a transparent
- * mapping of the top of memory space. Make it 0.5GByte for now,
- * so we can access on-board i/o areas.
- * Supervisor only access, so transparent mapping doesn't
- * clash with User code virtual address space.
- */
- mmu_map_tt #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
- jbra L(mmu_init_done)
- L(not6000):
- #endif /* CONFIG_BVME6000 */
- /*
- * mmu_init_mac
- *
- * The Macintosh mappings are less clear.
- *
- * Even as of this writing, it is unclear how the
- * Macintosh mappings will be done. However, as
- * the first author of this code I'm proposing the
- * following model:
- *
- * Map the kernel (that's already done),
- * Map the I/O (on most machines that's the
- * 0x5000.0000 ... 0x5300.0000 range,
- * Map the video frame buffer using as few pages
- * as absolutely (this requirement mostly stems from
- * the fact that when the frame buffer is at
- * 0x0000.0000 then we know there is valid RAM just
- * above the screen that we don't want to waste!).
- *
- * By the way, if the frame buffer is at 0x0000.0000
- * then the Macintosh is known as an RBV based Mac.
- *
- * By the way 2, the code currently maps in a bunch of
- * regions. But I'd like to cut that out. (And move most
- * of the mappings up into the kernel proper ... or only
- * map what's necessary.)
- */
- #ifdef CONFIG_MAC
- L(mmu_init_mac):
- is_not_mac(L(mmu_init_not_mac))
- putc 'F'
- is_not_040_or_060(1f)
- moveq #_PAGE_NOCACHE_S,%d3
- jbra 2f
- 1:
- moveq #_PAGE_NOCACHE030,%d3
- 2:
- /*
- * Mac Note: screen address of logical 0xF000.0000 -> <screen physical>
- * we simply map the 4MB that contains the videomem
- */
- movel #VIDEOMEMMASK,%d0
- andl %pc@(L(mac_videobase)),%d0
- mmu_map #VIDEOMEMBASE,%d0,#VIDEOMEMSIZE,%d3
- /* ROM from 4000 0000 to 4200 0000 (only for mac_reset()) */
- mmu_map_eq #0x40000000,#0x02000000,%d3
- /* IO devices (incl. serial port) from 5000 0000 to 5300 0000 */
- mmu_map_eq #0x50000000,#0x03000000,%d3
- /* Nubus slot space (video at 0xF0000000, rom at 0xF0F80000) */
- mmu_map_tt #1,#0xf8000000,#0x08000000,%d3
- jbra L(mmu_init_done)
- L(mmu_init_not_mac):
- #endif
- #ifdef CONFIG_SUN3X
- is_not_sun3x(L(notsun3x))
- /* oh, the pain.. We're gonna want the prom code after
- * starting the MMU, so we copy the mappings, translating
- * from 8k -> 4k pages as we go.
- */
- /* copy maps from 0xfee00000 to 0xff000000 */
- movel #0xfee00000, %d0
- moveq #ROOT_INDEX_SHIFT, %d1
- lsrl %d1,%d0
- mmu_get_root_table_entry %d0
- movel #0xfee00000, %d0
- moveq #PTR_INDEX_SHIFT, %d1
- lsrl %d1,%d0
- andl #PTR_TABLE_SIZE-1, %d0
- mmu_get_ptr_table_entry %a0,%d0
- movel #0xfee00000, %d0
- moveq #PAGE_INDEX_SHIFT, %d1
- lsrl %d1,%d0
- andl #PAGE_TABLE_SIZE-1, %d0
- mmu_get_page_table_entry %a0,%d0
- /* this is where the prom page table lives */
- movel 0xfefe00d4, %a1
- movel %a1@, %a1
- movel #((0x200000 >> 13)-1), %d1
- 1:
- movel %a1@+, %d3
- movel %d3,%a0@+
- addl #0x1000,%d3
- movel %d3,%a0@+
- dbra %d1,1b
- /* setup tt1 for I/O */
- mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
- jbra L(mmu_init_done)
- L(notsun3x):
- #endif
- #ifdef CONFIG_APOLLO
- is_not_apollo(L(notapollo))
- putc 'P'
- mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
- L(notapollo):
- jbra L(mmu_init_done)
- #endif
- L(mmu_init_done):
- putc 'G'
- leds 0x8
- /*
- * mmu_fixup
- *
- * On the 040 class machines, all pages that are used for the
- * mmu have to be fixed up. According to Motorola, pages holding mmu
- * tables should be non-cacheable on a '040 and write-through on a
- * '060. But analysis of the reasons for this, and practical
- * experience, showed that write-through also works on a '040.
- *
- * Allocated memory so far goes from kernel_end to memory_start that
- * is used for all kind of tables, for that the cache attributes
- * are now fixed.
- */
- L(mmu_fixup):
- is_not_040_or_060(L(mmu_fixup_done))
- #ifdef MMU_NOCACHE_KERNEL
- jbra L(mmu_fixup_done)
- #endif
- /* first fix the page at the start of the kernel, that
- * contains also kernel_pg_dir.
- */
- movel %pc@(L(phys_kernel_start)),%d0
- subl #PAGE_OFFSET,%d0
- lea %pc@(_stext),%a0
- subl %d0,%a0
- mmu_fixup_page_mmu_cache %a0
- movel %pc@(L(kernel_end)),%a0
- subl %d0,%a0
- movel %pc@(L(memory_start)),%a1
- subl %d0,%a1
- bra 2f
- 1:
- mmu_fixup_page_mmu_cache %a0
- addw #PAGESIZE,%a0
- 2:
- cmpl %a0,%a1
- jgt 1b
- L(mmu_fixup_done):
- #ifdef MMU_PRINT
- mmu_print
- #endif
- /*
- * mmu_engage
- *
- * This chunk of code performs the gruesome task of engaging the MMU.
- * The reason its gruesome is because when the MMU becomes engaged it
- * maps logical addresses to physical addresses. The Program Counter
- * register is then passed through the MMU before the next instruction
- * is fetched (the instruction following the engage MMU instruction).
- * This may mean one of two things:
- * 1. The Program Counter falls within the logical address space of
- * the kernel of which there are two sub-possibilities:
- * A. The PC maps to the correct instruction (logical PC == physical
- * code location), or
- * B. The PC does not map through and the processor will read some
- * data (or instruction) which is not the logically next instr.
- * As you can imagine, A is good and B is bad.
- * Alternatively,
- * 2. The Program Counter does not map through the MMU. The processor
- * will take a Bus Error.
- * Clearly, 2 is bad.
- * It doesn't take a wiz kid to figure you want 1.A.
- * This code creates that possibility.
- * There are two possible 1.A. states (we now ignore the other above states):
- * A. The kernel is located at physical memory addressed the same as
- * the logical memory for the kernel, i.e., 0x01000.
- * B. The kernel is located some where else. e.g., 0x0400.0000
- *
- * Under some conditions the Macintosh can look like A or B.
- * [A friend and I once noted that Apple hardware engineers should be
- * wacked twice each day: once when they show up at work (as in, Whack!,
- * "This is for the screwy hardware we know you're going to design today."),
- * and also at the end of the day (as in, Whack! "I don't know what
- * you designed today, but I'm sure it wasn't good."). -- rst]
- *
- * This code works on the following premise:
- * If the kernel start (%d5) is within the first 16 Meg of RAM,
- * then create a mapping for the kernel at logical 0x8000.0000 to
- * the physical location of the pc. And, create a transparent
- * translation register for the first 16 Meg. Then, after the MMU
- * is engaged, the PC can be moved up into the 0x8000.0000 range
- * and then the transparent translation can be turned off and then
- * the PC can jump to the correct logical location and it will be
- * home (finally). This is essentially the code that the Amiga used
- * to use. Now, it's generalized for all processors. Which means
- * that a fresh (but temporary) mapping has to be created. The mapping
- * is made in page 0 (an as of yet unused location -- except for the
- * stack!). This temporary mapping will only require 1 pointer table
- * and a single page table (it can map 256K).
- *
- * OK, alternatively, imagine that the Program Counter is not within
- * the first 16 Meg. Then, just use Transparent Translation registers
- * to do the right thing.
- *
- * Last, if _start is already at 0x01000, then there's nothing special
- * to do (in other words, in a degenerate case of the first case above,
- * do nothing).
- *
- * Let's do it.
- *
- *
- */
- putc 'H'
- mmu_engage
- /*
- * After this point no new memory is allocated and
- * the start of available memory is stored in availmem.
- * (The bootmem allocator requires now the physicall address.)
- */
- movel L(memory_start),availmem
- #ifdef CONFIG_AMIGA
- is_not_amiga(1f)
- /* fixup the Amiga custom register location before printing */
- clrl L(custom)
- 1:
- #endif
- #ifdef CONFIG_ATARI
- is_not_atari(1f)
- /* fixup the Atari iobase register location before printing */
- movel #0xff000000,L(iobase)
- 1:
- #endif
- #ifdef CONFIG_MAC
- is_not_mac(1f)
- movel #~VIDEOMEMMASK,%d0
- andl L(mac_videobase),%d0
- addl #VIDEOMEMBASE,%d0
- movel %d0,L(mac_videobase)
- #if defined(CONSOLE)
- movel %pc@(L(phys_kernel_start)),%d0
- subl #PAGE_OFFSET,%d0
- subl %d0,L(console_font)
- subl %d0,L(console_font_data)
- #endif
- #ifdef MAC_SERIAL_DEBUG
- orl #0x50000000,L(mac_sccbase)
- #endif
- 1:
- #endif
- #ifdef CONFIG_HP300
- is_not_hp300(1f)
- /*
- * Fix up the iobase register to point to the new location of the LEDs.
- */
- movel #0xf0000000,L(iobase)
- /*
- * Energise the FPU and caches.
- */
- is_040(1f)
- movel #0x60,0xf05f400c
- jbra 2f
- /*
- * 040: slightly different, apparently.
- */
- 1: movew #0,0xf05f400e
- movew #0x64,0xf05f400e
- 2:
- #endif
- #ifdef CONFIG_SUN3X
- is_not_sun3x(1f)
- /* enable copro */
- oriw #0x4000,0x61000000
- 1:
- #endif
- #ifdef CONFIG_APOLLO
- is_not_apollo(1f)
- /*
- * Fix up the iobase before printing
- */
- movel #0x80000000,L(iobase)
- 1:
- #endif
- putc 'I'
- leds 0x10
- /*
- * Enable caches
- */
- is_not_040_or_060(L(cache_not_680460))
- L(cache680460):
- .chip 68040
- nop
- cpusha %bc
- nop
- is_060(L(cache68060))
- movel #CC6_ENABLE_D+CC6_ENABLE_I,%d0
- /* MMU stuff works in copyback mode now, so enable the cache */
- movec %d0,%cacr
- jra L(cache_done)
- L(cache68060):
- movel #CC6_ENABLE_D+CC6_ENABLE_I+CC6_ENABLE_SB+CC6_PUSH_DPI+CC6_ENABLE_B+CC6_CLRA_B,%d0
- /* MMU stuff works in copyback mode now, so enable the cache */
- movec %d0,%cacr
- /* enable superscalar dispatch in PCR */
- moveq #1,%d0
- .chip 68060
- movec %d0,%pcr
- jbra L(cache_done)
- L(cache_not_680460):
- L(cache68030):
- .chip 68030
- movel #CC3_ENABLE_DB+CC3_CLR_D+CC3_ENABLE_D+CC3_ENABLE_IB+CC3_CLR_I+CC3_ENABLE_I,%d0
- movec %d0,%cacr
- jra L(cache_done)
- .chip 68k
- L(cache_done):
- putc 'J'
- /*
- * Setup initial stack pointer
- */
- lea init_task,%curptr
- lea init_thread_union+THREAD_SIZE,%sp
- putc 'K'
- subl %a6,%a6 /* clear a6 for gdb */
- /*
- * The new 64bit printf support requires an early exception initialization.
- */
- jbsr base_trap_init
- /* jump to the kernel start */
- putc '\n'
- leds 0x55
- jbsr start_kernel
- /*
- * Find a tag record in the bootinfo structure
- * The bootinfo structure is located right after the kernel bss
- * Returns: d0: size (-1 if not found)
- * a0: data pointer (end-of-records if not found)
- */
- func_start get_bi_record,%d1
- movel ARG1,%d0
- lea %pc@(_end),%a0
- 1: tstw %a0@(BIR_TAG)
- jeq 3f
- cmpw %a0@(BIR_TAG),%d0
- jeq 2f
- addw %a0@(BIR_SIZE),%a0
- jra 1b
- 2: moveq #0,%d0
- movew %a0@(BIR_SIZE),%d0
- lea %a0@(BIR_DATA),%a0
- jra 4f
- 3: moveq #-1,%d0
- lea %a0@(BIR_SIZE),%a0
- 4:
- func_return get_bi_record
- /*
- * MMU Initialization Begins Here
- *
- * The structure of the MMU tables on the 68k machines
- * is thus:
- * Root Table
- * Logical addresses are translated through
- * a hierarchical translation mechanism where the high-order
- * seven bits of the logical address (LA) are used as an
- * index into the "root table." Each entry in the root
- * table has a bit which specifies if it's a valid pointer to a
- * pointer table. Each entry defines a 32KMeg range of memory.
- * If an entry is invalid then that logical range of 32M is
- * invalid and references to that range of memory (when the MMU
- * is enabled) will fault. If the entry is valid, then it does
- * one of two things. On 040/060 class machines, it points to
- * a pointer table which then describes more finely the memory
- * within that 32M range. On 020/030 class machines, a technique
- * called "early terminating descriptors" are used. This technique
- * allows an entire 32Meg to be described by a single entry in the
- * root table. Thus, this entry in the root table, contains the
- * physical address of the memory or I/O at the logical address
- * which the entry represents and it also contains the necessary
- * cache bits for this region.
- *
- * Pointer Tables
- * Per the Root Table, there will be one or more
- * pointer tables. Each pointer table defines a 32M range.
- * Not all of the 32M range need be defined. Again, the next
- * seven bits of the logical address are used an index into
- * the pointer table to point to page tables (if the pointer
- * is valid). There will undoubtedly be more than one
- * pointer table for the kernel because each pointer table
- * defines a range of only 32M. Valid pointer table entries
- * point to page tables, or are early terminating entries
- * themselves.
- *
- * Page Tables
- * Per the Pointer Tables, each page table entry points
- * to the physical page in memory that supports the logical
- * address that translates to the particular index.
- *
- * In short, the Logical Address gets translated as follows:
- * bits 31..26 - index into the Root Table
- * bits 25..18 - index into the Pointer Table
- * bits 17..12 - index into the Page Table
- * bits 11..0 - offset into a particular 4K page
- *
- * The algorithms which follows do one thing: they abstract
- * the MMU hardware. For example, there are three kinds of
- * cache settings that are relevant. Either, memory is
- * being mapped in which case it is either Kernel Code (or
- * the RamDisk) or it is MMU data. On the 030, the MMU data
- * option also describes the kernel. Or, I/O is being mapped
- * in which case it has its own kind of cache bits. There
- * are constants which abstract these notions from the code that
- * actually makes the call to map some range of memory.
- *
- *
- *
- */
- #ifdef MMU_PRINT
- /*
- * mmu_print
- *
- * This algorithm will print out the current MMU mappings.
- *
- * Input:
- * %a5 points to the root table. Everything else is calculated
- * from this.
- */
- #define mmu_next_valid 0
- #define mmu_start_logical 4
- #define mmu_next_logical 8
- #define mmu_start_physical 12
- #define mmu_next_physical 16
- #define MMU_PRINT_INVALID -1
- #define MMU_PRINT_VALID 1
- #define MMU_PRINT_UNINITED 0
- #define putZc(z,n) jbne 1f; putc z; jbra 2f; 1: putc n; 2:
- func_start mmu_print,%a0-%a6/%d0-%d7
- movel %pc@(L(kernel_pgdir_ptr)),%a5
- lea %pc@(L(mmu_print_data)),%a0
- movel #MMU_PRINT_UNINITED,%a0@(mmu_next_valid)
- is_not_040_or_060(mmu_030_print)
- mmu_040_print:
- puts "\nMMU040\n"
- puts "rp:"
- putn %a5
- putc '\n'
- #if 0
- /*
- * The following #if/#endif block is a tight algorithm for dumping the 040
- * MMU Map in gory detail. It really isn't that practical unless the
- * MMU Map algorithm appears to go awry and you need to debug it at the
- * entry per entry level.
- */
- movel #ROOT_TABLE_SIZE,%d5
- #if 0
- movel %a5@+,%d7 | Burn an entry to skip the kernel mappings,
- subql #1,%d5 | they (might) work
- #endif
- 1: tstl %d5
- jbeq mmu_print_done
- subq #1,%d5
- movel %a5@+,%d7
- btst #1,%d7
- jbeq 1b
- 2: putn %d7
- andil #0xFFFFFE00,%d7
- movel %d7,%a4
- movel #PTR_TABLE_SIZE,%d4
- putc ' '
- 3: tstl %d4
- jbeq 11f
- subq #1,%d4
- movel %a4@+,%d7
- btst #1,%d7
- jbeq 3b
- 4: putn %d7
- andil #0xFFFFFF00,%d7
- movel %d7,%a3
- movel #PAGE_TABLE_SIZE,%d3
- 5: movel #8,%d2
- 6: tstl %d3
- jbeq 31f
- subq #1,%d3
- movel %a3@+,%d6
- btst #0,%d6
- jbeq 6b
- 7: tstl %d2
- jbeq 8f
- subq #1,%d2
- putc ' '
- jbra 91f
- 8: putc '\n'
- movel #8+1+8+1+1,%d2
- 9: putc ' '
- dbra %d2,9b
- movel #7,%d2
- 91: putn %d6
- jbra 6b
- 31: putc '\n'
- movel #8+1,%d2
- 32: putc ' '
- dbra %d2,32b
- jbra 3b
- 11: putc '\n'
- jbra 1b
- #endif /* MMU 040 Dumping code that's gory and detailed */
- lea %pc@(kernel_pg_dir),%a5
- movel %a5,%a0 /* a0 has the address of the root table ptr */
- movel #0x00000000,%a4 /* logical address */
- moveql #0,%d0
- 40:
- /* Increment the logical address and preserve in d5 */
- movel %a4,%d5
- addil #PAGESIZE<<13,%d5
- movel %a0@+,%d6
- btst #1,%d6
- jbne 41f
- jbsr mmu_print_tuple_invalidate
- jbra 48f
- 41:
- movel #0,%d1
- andil #0xfffffe00,%d6
- movel %d6,%a1
- 42:
- movel %a4,%d5
- addil #PAGESIZE<<6,%d5
- movel %a1@+,%d6
- btst #1,%d6
- jbne 43f
- jbsr mmu_print_tuple_invalidate
- jbra 47f
- 43:
- movel #0,%d2
- andil #0xffffff00,%d6
- movel %d6,%a2
- 44:
- movel %a4,%d5
- addil #PAGESIZE,%d5
- movel %a2@+,%d6
- btst #0,%d6
- jbne 45f
- jbsr mmu_print_tuple_invalidate
- jbra 46f
- 45:
- moveml %d0-%d1,%sp@-
- movel %a4,%d0
- movel %d6,%d1
- andil #0xfffff4e0,%d1
- lea %pc@(mmu_040_print_flags),%a6
- jbsr mmu_print_tuple
- moveml %sp@+,%d0-%d1
- 46:
- movel %d5,%a4
- addq #1,%d2
- cmpib #64,%d2
- jbne 44b
- 47:
- movel %d5,%a4
- addq #1,%d1
- cmpib #128,%d1
- jbne 42b
- 48:
- movel %d5,%a4 /* move to the next logical address */
- addq #1,%d0
- cmpib #128,%d0
- jbne 40b
- .chip 68040
- movec %dtt1,%d0
- movel %d0,%d1
- andiw #0x8000,%d1 /* is it valid ? */
- jbeq 1f /* No, bail out */
- movel %d0,%d1
- andil #0xff000000,%d1 /* Get the address */
- putn %d1
- puts "=="
- putn %d1
- movel %d0,%d6
- jbsr mmu_040_print_flags_tt
- 1:
- movec %dtt0,%d0
- movel %d0,%d1
- andiw #0x8000,%d1 /* is it valid ? */
- jbeq 1f /* No, bail out */
- movel %d0,%d1
- andil #0xff000000,%d1 /* Get the address */
- putn %d1
- puts "=="
- putn %d1
- movel %d0,%d6
- jbsr mmu_040_print_flags_tt
- 1:
- .chip 68k
- jbra mmu_print_done
- mmu_040_print_flags:
- btstl #10,%d6
- putZc(' ','G') /* global bit */
- btstl #7,%d6
- putZc(' ','S') /* supervisor bit */
- mmu_040_print_flags_tt:
- btstl #6,%d6
- jbne 3f
- putc 'C'
- btstl #5,%d6
- putZc('w','c') /* write through or copy-back */
- jbra 4f
- 3:
- putc 'N'
- btstl #5,%d6
- putZc('s',' ') /* serialized non-cacheable, or non-cacheable */
- 4:
- rts
- mmu_030_print_flags:
- btstl #6,%d6
- putZc('C','I') /* write through or copy-back */
- rts
- mmu_030_print:
- puts "\nMMU030\n"
- puts "\nrp:"
- putn %a5
- putc '\n'
- movel %a5,%d0
- andil #0xfffffff0,%d0
- movel %d0,%a0
- movel #0x00000000,%a4 /* logical address */
- movel #0,%d0
- 30:
- movel %a4,%d5
- addil #PAGESIZE<<13,%d5
- movel %a0@+,%d6
- btst #1,%d6 /* is it a table ptr? */
- jbne 31f /* yes */
- btst #0,%d6 /* is it early terminating? */
- jbeq 1f /* no */
- jbsr mmu_030_print_helper
- jbra 38f
- 1:
- jbsr mmu_print_tuple_invalidate
- jbra 38f
- 31:
- movel #0,%d1
- andil #0xfffffff0,%d6
- movel %d6,%a1
- 32:
- movel %a4,%d5
- addil #PAGESIZE<<6,%d5
- movel %a1@+,%d6
- btst #1,%d6 /* is it a table ptr? */
- jbne 33f /* yes */
- btst #0,%d6 /* is it a page descriptor? */
- jbeq 1f /* no */
- jbsr mmu_030_print_helper
- jbra 37f
- 1:
- jbsr mmu_print_tuple_invalidate
- jbra 37f
- 33:
- movel #0,%d2
- andil #0xfffffff0,%d6
- movel %d6,%a2
- 34:
- movel %a4,%d5
- addil #PAGESIZE,%d5
- movel %a2@+,%d6
- btst #0,%d6
- jbne 35f
- jbsr mmu_print_tuple_invalidate
- jbra 36f
- 35:
- jbsr mmu_030_print_helper
- 36:
- movel %d5,%a4
- addq #1,%d2
- cmpib #64,%d2
- jbne 34b
- 37:
- movel %d5,%a4
- addq #1,%d1
- cmpib #128,%d1
- jbne 32b
- 38:
- movel %d5,%a4 /* move to the next logical address */
- addq #1,%d0
- cmpib #128,%d0
- jbne 30b
- mmu_print_done:
- puts "\n\n"
- func_return mmu_print
- mmu_030_print_helper:
- moveml %d0-%d1,%sp@-
- movel %a4,%d0
- movel %d6,%d1
- lea %pc@(mmu_030_print_flags),%a6
- jbsr mmu_print_tuple
- moveml %sp@+,%d0-%d1
- rts
- mmu_print_tuple_invalidate:
- moveml %a0/%d7,%sp@-
- lea %pc@(L(mmu_print_data)),%a0
- tstl %a0@(mmu_next_valid)
- jbmi mmu_print_tuple_invalidate_exit
- movel #MMU_PRINT_INVALID,%a0@(mmu_next_valid)
- putn %a4
- puts "##\n"
- mmu_print_tuple_invalidate_exit:
- moveml %sp@+,%a0/%d7
- rts
- mmu_print_tuple:
- moveml %d0-%d7/%a0,%sp@-
- lea %pc@(L(mmu_print_data)),%a0
- tstl %a0@(mmu_next_valid)
- jble mmu_print_tuple_print
- cmpl %a0@(mmu_next_physical),%d1
- jbeq mmu_print_tuple_increment
- mmu_print_tuple_print:
- putn %d0
- puts "->"
- putn %d1
- movel %d1,%d6
- jbsr %a6@
- mmu_print_tuple_record:
- movel #MMU_PRINT_VALID,%a0@(mmu_next_valid)
- movel %d1,%a0@(mmu_next_physical)
- mmu_print_tuple_increment:
- movel %d5,%d7
- subl %a4,%d7
- addl %d7,%a0@(mmu_next_physical)
- mmu_print_tuple_exit:
- moveml %sp@+,%d0-%d7/%a0
- rts
- mmu_print_machine_cpu_types:
- puts "machine: "
- is_not_amiga(1f)
- puts "amiga"
- jbra 9f
- 1:
- is_not_atari(2f)
- puts "atari"
- jbra 9f
- 2:
- is_not_mac(3f)
- puts "macintosh"
- jbra 9f
- 3: puts "unknown"
- 9: putc '\n'
- puts "cputype: 0"
- is_not_060(1f)
- putc '6'
- jbra 9f
- 1:
- is_not_040_or_060(2f)
- putc '4'
- jbra 9f
- 2: putc '3'
- 9: putc '0'
- putc '\n'
- rts
- #endif /* MMU_PRINT */
- /*
- * mmu_map_tt
- *
- * This is a specific function which works on all 680x0 machines.
- * On 030, 040 & 060 it will attempt to use Transparent Translation
- * registers (tt1).
- * On 020 it will call the standard mmu_map which will use early
- * terminating descriptors.
- */
- func_start mmu_map_tt,%d0/%d1/%a0,4
- dputs "mmu_map_tt:"
- dputn ARG1
- dputn ARG2
- dputn ARG3
- dputn ARG4
- dputc '\n'
- is_020(L(do_map))
- /* Extract the highest bit set
- */
- bfffo ARG3{#0,#32},%d1
- cmpw #8,%d1
- jcc L(do_map)
- /* And get the mask
- */
- moveq #-1,%d0
- lsrl %d1,%d0
- lsrl #1,%d0
- /* Mask the address
- */
- movel %d0,%d1
- notl %d1
- andl ARG2,%d1
- /* Generate the upper 16bit of the tt register
- */
- lsrl #8,%d0
- orl %d0,%d1
- clrw %d1
- is_040_or_060(L(mmu_map_tt_040))
- /* set 030 specific bits (read/write access for supervisor mode
- * (highest function code set, lower two bits masked))
- */
- orw #TTR_ENABLE+TTR_RWM+TTR_FCB2+TTR_FCM1+TTR_FCM0,%d1
- movel ARG4,%d0
- btst #6,%d0
- jeq 1f
- orw #TTR_CI,%d1
- 1: lea STACK,%a0
- dputn %d1
- movel %d1,%a0@
- .chip 68030
- tstl ARG1
- jne 1f
- pmove %a0@,%tt0
- jra 2f
- 1: pmove %a0@,%tt1
- 2: .chip 68k
- jra L(mmu_map_tt_done)
- /* set 040 specific bits
- */
- L(mmu_map_tt_040):
- orw #TTR_ENABLE+TTR_KERNELMODE,%d1
- orl ARG4,%d1
- dputn %d1
- .chip 68040
- tstl ARG1
- jne 1f
- movec %d1,%itt0
- movec %d1,%dtt0
- jra 2f
- 1: movec %d1,%itt1
- movec %d1,%dtt1
- 2: .chip 68k
- jra L(mmu_map_tt_done)
- L(do_map):
- mmu_map_eq ARG2,ARG3,ARG4
- L(mmu_map_tt_done):
- func_return mmu_map_tt
- /*
- * mmu_map
- *
- * This routine will map a range of memory using a pointer
- * table and allocating the pages on the fly from the kernel.
- * The pointer table does not have to be already linked into
- * the root table, this routine will do that if necessary.
- *
- * NOTE
- * This routine will assert failure and use the serial_putc
- * routines in the case of a run-time error. For example,
- * if the address is already mapped.
- *
- * NOTE-2
- * This routine will use early terminating descriptors
- * where possible for the 68020+68851 and 68030 type
- * processors.
- */
- func_start mmu_map,%d0-%d4/%a0-%a4
- dputs "\nmmu_map:"
- dputn ARG1
- dputn ARG2
- dputn ARG3
- dputn ARG4
- dputc '\n'
- /* Get logical address and round it down to 256KB
- */
- movel ARG1,%d0
- andl #-(PAGESIZE*PAGE_TABLE_SIZE),%d0
- movel %d0,%a3
- /* Get the end address
- */
- movel ARG1,%a4
- addl ARG3,%a4
- subql #1,%a4
- /* Get physical address and round it down to 256KB
- */
- movel ARG2,%d0
- andl #-(PAGESIZE*PAGE_TABLE_SIZE),%d0
- movel %d0,%a2
- /* Add page attributes to the physical address
- */
- movel ARG4,%d0
- orw #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
- addw %d0,%a2
- dputn %a2
- dputn %a3
- dputn %a4
- is_not_040_or_060(L(mmu_map_030))
- addw #_PAGE_GLOBAL040,%a2
- /*
- * MMU 040 & 060 Support
- *
- * The MMU usage for the 040 and 060 is different enough from
- * the 030 and 68851 that there is separate code. This comment
- * block describes the data structures and algorithms built by
- * this code.
- *
- * The 040 does not support early terminating descriptors, as
- * the 030 does. Therefore, a third level of table is needed
- * for the 040, and that would be the page table. In Linux,
- * page tables are allocated directly from the memory above the
- * kernel.
- *
- */
- L(mmu_map_040):
- /* Calculate the offset into the root table
- */
- movel %a3,%d0
- moveq #ROOT_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- mmu_get_root_table_entry %d0
- /* Calculate the offset into the pointer table
- */
- movel %a3,%d0
- moveq #PTR_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- andl #PTR_TABLE_SIZE-1,%d0
- mmu_get_ptr_table_entry %a0,%d0
- /* Calculate the offset into the page table
- */
- movel %a3,%d0
- moveq #PAGE_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- andl #PAGE_TABLE_SIZE-1,%d0
- mmu_get_page_table_entry %a0,%d0
- /* The page table entry must not no be busy
- */
- tstl %a0@
- jne L(mmu_map_error)
- /* Do the mapping and advance the pointers
- */
- movel %a2,%a0@
- 2:
- addw #PAGESIZE,%a2
- addw #PAGESIZE,%a3
- /* Ready with mapping?
- */
- lea %a3@(-1),%a0
- cmpl %a0,%a4
- jhi L(mmu_map_040)
- jra L(mmu_map_done)
- L(mmu_map_030):
- /* Calculate the offset into the root table
- */
- movel %a3,%d0
- moveq #ROOT_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- mmu_get_root_table_entry %d0
- /* Check if logical address 32MB aligned,
- * so we can try to map it once
- */
- movel %a3,%d0
- andl #(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1)&(-ROOT_TABLE_SIZE),%d0
- jne 1f
- /* Is there enough to map for 32MB at once
- */
- lea %a3@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1),%a1
- cmpl %a1,%a4
- jcs 1f
- addql #1,%a1
- /* The root table entry must not no be busy
- */
- tstl %a0@
- jne L(mmu_map_error)
- /* Do the mapping and advance the pointers
- */
- dputs "early term1"
- dputn %a2
- dputn %a3
- dputn %a1
- dputc '\n'
- movel %a2,%a0@
- movel %a1,%a3
- lea %a2@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE),%a2
- jra L(mmu_mapnext_030)
- 1:
- /* Calculate the offset into the pointer table
- */
- movel %a3,%d0
- moveq #PTR_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- andl #PTR_TABLE_SIZE-1,%d0
- mmu_get_ptr_table_entry %a0,%d0
- /* The pointer table entry must not no be busy
- */
- tstl %a0@
- jne L(mmu_map_error)
- /* Do the mapping and advance the pointers
- */
- dputs "early term2"
- dputn %a2
- dputn %a3
- dputc '\n'
- movel %a2,%a0@
- addl #PAGE_TABLE_SIZE*PAGESIZE,%a2
- addl #PAGE_TABLE_SIZE*PAGESIZE,%a3
- L(mmu_mapnext_030):
- /* Ready with mapping?
- */
- lea %a3@(-1),%a0
- cmpl %a0,%a4
- jhi L(mmu_map_030)
- jra L(mmu_map_done)
- L(mmu_map_error):
- dputs "mmu_map error:"
- dputn %a2
- dputn %a3
- dputc '\n'
- L(mmu_map_done):
- func_return mmu_map
- /*
- * mmu_fixup
- *
- * On the 040 class machines, all pages that are used for the
- * mmu have to be fixed up.
- */
- func_start mmu_fixup_page_mmu_cache,%d0/%a0
- dputs "mmu_fixup_page_mmu_cache"
- dputn ARG1
- /* Calculate the offset into the root table
- */
- movel ARG1,%d0
- moveq #ROOT_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- mmu_get_root_table_entry %d0
- /* Calculate the offset into the pointer table
- */
- movel ARG1,%d0
- moveq #PTR_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- andl #PTR_TABLE_SIZE-1,%d0
- mmu_get_ptr_table_entry %a0,%d0
- /* Calculate the offset into the page table
- */
- movel ARG1,%d0
- moveq #PAGE_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- andl #PAGE_TABLE_SIZE-1,%d0
- mmu_get_page_table_entry %a0,%d0
- movel %a0@,%d0
- andil #_CACHEMASK040,%d0
- orl %pc@(m68k_pgtable_cachemode),%d0
- movel %d0,%a0@
- dputc '\n'
- func_return mmu_fixup_page_mmu_cache
- /*
- * mmu_temp_map
- *
- * create a temporary mapping to enable the mmu,
- * this we don't need any transparation translation tricks.
- */
- func_start mmu_temp_map,%d0/%d1/%a0/%a1
- dputs "mmu_temp_map"
- dputn ARG1
- dputn ARG2
- dputc '\n'
- lea %pc@(L(temp_mmap_mem)),%a1
- /* Calculate the offset in the root table
- */
- movel ARG2,%d0
- moveq #ROOT_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- mmu_get_root_table_entry %d0
- /* Check if the table is temporary allocated, so we have to reuse it
- */
- movel %a0@,%d0
- cmpl %pc@(L(memory_start)),%d0
- jcc 1f
- /* Temporary allocate a ptr table and insert it into the root table
- */
- movel %a1@,%d0
- addl #PTR_TABLE_SIZE*4,%a1@
- orw #_PAGE_TABLE+_PAGE_ACCESSED,%d0
- movel %d0,%a0@
- dputs " (new)"
- 1:
- dputn %d0
- /* Mask the root table entry for the ptr table
- */
- andw #-ROOT_TABLE_SIZE,%d0
- movel %d0,%a0
- /* Calculate the offset into the pointer table
- */
- movel ARG2,%d0
- moveq #PTR_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- andl #PTR_TABLE_SIZE-1,%d0
- lea %a0@(%d0*4),%a0
- dputn %a0
- /* Check if a temporary page table is already allocated
- */
- movel %a0@,%d0
- jne 1f
- /* Temporary allocate a page table and insert it into the ptr table
- */
- movel %a1@,%d0
- /* The 512 should be PAGE_TABLE_SIZE*4, but that violates the
- alignment restriction for pointer tables on the '0[46]0. */
- addl #512,%a1@
- orw #_PAGE_TABLE+_PAGE_ACCESSED,%d0
- movel %d0,%a0@
- dputs " (new)"
- 1:
- dputn %d0
- /* Mask the ptr table entry for the page table
- */
- andw #-PTR_TABLE_SIZE,%d0
- movel %d0,%a0
- /* Calculate the offset into the page table
- */
- movel ARG2,%d0
- moveq #PAGE_INDEX_SHIFT,%d1
- lsrl %d1,%d0
- andl #PAGE_TABLE_SIZE-1,%d0
- lea %a0@(%d0*4),%a0
- dputn %a0
- /* Insert the address into the page table
- */
- movel ARG1,%d0
- andw #-PAGESIZE,%d0
- orw #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
- movel %d0,%a0@
- dputn %d0
- dputc '\n'
- func_return mmu_temp_map
- func_start mmu_engage,%d0-%d2/%a0-%a3
- moveq #ROOT_TABLE_SIZE-1,%d0
- /* Temporarily use a different root table. */
- lea %pc@(L(kernel_pgdir_ptr)),%a0
- movel %a0@,%a2
- movel %pc@(L(memory_start)),%a1
- movel %a1,%a0@
- movel %a2,%a0
- 1:
- movel %a0@+,%a1@+
- dbra %d0,1b
- lea %pc@(L(temp_mmap_mem)),%a0
- movel %a1,%a0@
- movew #PAGESIZE-1,%d0
- 1:
- clrl %a1@+
- dbra %d0,1b
- lea %pc@(1b),%a0
- movel #1b,%a1
- /* Skip temp mappings if phys == virt */
- cmpl %a0,%a1
- jeq 1f
- mmu_temp_map %a0,%a0
- mmu_temp_map %a0,%a1
- addw #PAGESIZE,%a0
- addw #PAGESIZE,%a1
- mmu_temp_map %a0,%a0
- mmu_temp_map %a0,%a1
- 1:
- movel %pc@(L(memory_start)),%a3
- movel %pc@(L(phys_kernel_start)),%d2
- is_not_040_or_060(L(mmu_engage_030))
- L(mmu_engage_040):
- .chip 68040
- nop
- cinva %bc
- nop
- pflusha
- nop
- movec %a3,%srp
- movel #TC_ENABLE+TC_PAGE4K,%d0
- movec %d0,%tc /* enable the MMU */
- jmp 1f:l
- 1: nop
- movec %a2,%srp
- nop
- cinva %bc
- nop
- pflusha
- .chip 68k
- jra L(mmu_engage_cleanup)
- L(mmu_engage_030_temp):
- .space 12
- L(mmu_engage_030):
- .chip 68030
- lea %pc@(L(mmu_engage_030_temp)),%a0
- movel #0x80000002,%a0@
- movel %a3,%a0@(4)
- movel #0x0808,%d0
- movec %d0,%cacr
- pmove %a0@,%srp
- pflusha
- /*
- * enable,super root enable,4096 byte pages,7 bit root index,
- * 7 bit pointer index, 6 bit page table index.
- */
- movel #0x82c07760,%a0@(8)
- pmove %a0@(8),%tc /* enable the MMU */
- jmp 1f:l
- 1: movel %a2,%a0@(4)
- movel #0x0808,%d0
- movec %d0,%cacr
- pmove %a0@,%srp
- pflusha
- .chip 68k
- L(mmu_engage_cleanup):
- subl #PAGE_OFFSET,%d2
- subl %d2,%a2
- movel %a2,L(kernel_pgdir_ptr)
- subl %d2,%fp
- subl %d2,%sp
- subl %d2,ARG0
- func_return mmu_engage
- func_start mmu_get_root_table_entry,%d0/%a1
- #if 0
- dputs "mmu_get_root_table_entry:"
- dputn ARG1
- dputs " ="
- #endif
- movel %pc@(L(kernel_pgdir_ptr)),%a0
- tstl %a0
- jne 2f
- dputs "\nmmu_init:"
- /* Find the start of free memory, get_bi_record does this for us,
- * as the bootinfo structure is located directly behind the kernel
- * and and we simply search for the last entry.
- */
- get_bi_record BI_LAST
- addw #PAGESIZE-1,%a0
- movel %a0,%d0
- andw #-PAGESIZE,%d0
- dputn %d0
- lea %pc@(L(memory_start)),%a0
- movel %d0,%a0@
- lea %pc@(L(kernel_end)),%a0
- movel %d0,%a0@
- /* we have to return the first page at _stext since the init code
- * in mm/init.c simply expects kernel_pg_dir there, the rest of
- * page is used for further ptr tables in get_ptr_table.
- */
- lea %pc@(_stext),%a0
- lea %pc@(L(mmu_cached_pointer_tables)),%a1
- movel %a0,%a1@
- addl #ROOT_TABLE_SIZE*4,%a1@
- lea %pc@(L(mmu_num_pointer_tables)),%a1
- addql #1,%a1@
- /* clear the page
- */
- movel %a0,%a1
- movew #PAGESIZE/4-1,%d0
- 1:
- clrl %a1@+
- dbra %d0,1b
- lea %pc@(L(kernel_pgdir_ptr)),%a1
- movel %a0,%a1@
- dputn %a0
- dputc '\n'
- 2:
- movel ARG1,%d0
- lea %a0@(%d0*4),%a0
- #if 0
- dputn %a0
- dputc '\n'
- #endif
- func_return mmu_get_root_table_entry
- func_start mmu_get_ptr_table_entry,%d0/%a1
- #if 0
- dputs "mmu_get_ptr_table_entry:"
- dputn ARG1
- dputn ARG2
- dputs " ="
- #endif
- movel ARG1,%a0
- movel %a0@,%d0
- jne 2f
- /* Keep track of the number of pointer tables we use
- */
- dputs "\nmmu_get_new_ptr_table:"
- lea %pc@(L(mmu_num_pointer_tables)),%a0
- movel %a0@,%d0
- addql #1,%a0@
- /* See if there is a free pointer table in our cache of pointer tables
- */
- lea %pc@(L(mmu_cached_pointer_tables)),%a1
- andw #7,%d0
- jne 1f
- /* Get a new pointer table page from above the kernel memory
- */
- get_new_page
- movel %a0,%a1@
- 1:
- /* There is an unused pointer table in our cache... use it
- */
- movel %a1@,%d0
- addl #PTR_TABLE_SIZE*4,%a1@
- dputn %d0
- dputc '\n'
- /* Insert the new pointer table into the root table
- */
- movel ARG1,%a0
- orw #_PAGE_TABLE+_PAGE_ACCESSED,%d0
- movel %d0,%a0@
- 2:
- /* Extract the pointer table entry
- */
- andw #-PTR_TABLE_SIZE,%d0
- movel %d0,%a0
- movel ARG2,%d0
- lea %a0@(%d0*4),%a0
- #if 0
- dputn %a0
- dputc '\n'
- #endif
- func_return mmu_get_ptr_table_entry
- func_start mmu_get_page_table_entry,%d0/%a1
- #if 0
- dputs "mmu_get_page_table_entry:"
- dputn ARG1
- dputn ARG2
- dputs " ="
- #endif
- movel ARG1,%a0
- movel %a0@,%d0
- jne 2f
- /* If the page table entry doesn't exist, we allocate a complete new
- * page and use it as one continues big page table which can cover
- * 4MB of memory, nearly almost all mappings have that alignment.
- */
- get_new_page
- addw #_PAGE_TABLE+_PAGE_ACCESSED,%a0
- /* align pointer table entry for a page of page tables
- */
- movel ARG1,%d0
- andw #-(PAGESIZE/PAGE_TABLE_SIZE),%d0
- movel %d0,%a1
- /* Insert the page tables into the pointer entries
- */
- moveq #PAGESIZE/PAGE_TABLE_SIZE/4-1,%d0
- 1:
- movel %a0,%a1@+
- lea %a0@(PAGE_TABLE_SIZE*4),%a0
- dbra %d0,1b
- /* Now we can get the initialized pointer table entry
- */
- movel ARG1,%a0
- movel %a0@,%d0
- 2:
- /* Extract the page table entry
- */
- andw #-PAGE_TABLE_SIZE,%d0
- movel %d0,%a0
- movel ARG2,%d0
- lea %a0@(%d0*4),%a0
- #if 0
- dputn %a0
- dputc '\n'
- #endif
- func_return mmu_get_page_table_entry
- /*
- * get_new_page
- *
- * Return a new page from the memory start and clear it.
- */
- func_start get_new_page,%d0/%a1
- dputs "\nget_new_page:"
- /* allocate the page and adjust memory_start
- */
- lea %pc@(L(memory_start)),%a0
- movel %a0@,%a1
- addl #PAGESIZE,%a0@
- /* clear the new page
- */
- movel %a1,%a0
- movew #PAGESIZE/4-1,%d0
- 1:
- clrl %a1@+
- dbra %d0,1b
- dputn %a0
- dputc '\n'
- func_return get_new_page
- /*
- * Debug output support
- * Atarians have a choice between the parallel port, the serial port
- * from the MFP or a serial port of the SCC
- */
- #ifdef CONFIG_MAC
- L(scc_initable_mac):
- .byte 9,12 /* Reset */
- .byte 4,0x44 /* x16, 1 stopbit, no parity */
- .byte 3,0xc0 /* receiver: 8 bpc */
- .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
- .byte 9,0 /* no interrupts */
- .byte 10,0 /* NRZ */
- .byte 11,0x50 /* use baud rate generator */
- .byte 12,10,13,0 /* 9600 baud */
- .byte 14,1 /* Baud rate generator enable */
- .byte 3,0xc1 /* enable receiver */
- .byte 5,0xea /* enable transmitter */
- .byte -1
- .even
- #endif
- #ifdef CONFIG_ATARI
- /* #define USE_PRINTER */
- /* #define USE_SCC_B */
- /* #define USE_SCC_A */
- #define USE_MFP
- #if defined(USE_SCC_A) || defined(USE_SCC_B)
- #define USE_SCC
- /* Initialisation table for SCC */
- L(scc_initable):
- .byte 9,12 /* Reset */
- .byte 4,0x44 /* x16, 1 stopbit, no parity */
- .byte 3,0xc0 /* receiver: 8 bpc */
- .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
- .byte 9,0 /* no interrupts */
- .byte 10,0 /* NRZ */
- .byte 11,0x50 /* use baud rate generator */
- .byte 12,24,13,0 /* 9600 baud */
- .byte 14,2,14,3 /* use master clock for BRG, enable */
- .byte 3,0xc1 /* enable receiver */
- .byte 5,0xea /* enable transmitter */
- .byte -1
- .even
- #endif
- #ifdef USE_PRINTER
- LPSG_SELECT = 0xff8800
- LPSG_READ = 0xff8800
- LPSG_WRITE = 0xff8802
- LPSG_IO_A = 14
- LPSG_IO_B = 15
- LPSG_CONTROL = 7
- LSTMFP_GPIP = 0xfffa01
- LSTMFP_DDR = 0xfffa05
- LSTMFP_IERB = 0xfffa09
- #elif defined(USE_SCC_B)
- LSCC_CTRL = 0xff8c85
- LSCC_DATA = 0xff8c87
- #elif defined(USE_SCC_A)
- LSCC_CTRL = 0xff8c81
- LSCC_DATA = 0xff8c83
- #elif defined(USE_MFP)
- LMFP_UCR = 0xfffa29
- LMFP_TDCDR = 0xfffa1d
- LMFP_TDDR = 0xfffa25
- LMFP_TSR = 0xfffa2d
- LMFP_UDR = 0xfffa2f
- #endif
- #endif /* CONFIG_ATARI */
- /*
- * Serial port output support.
- */
- /*
- * Initialize serial port hardware for 9600/8/1
- */
- func_start serial_init,%d0/%d1/%a0/%a1
- /*
- * Some of the register usage that follows
- * CONFIG_AMIGA
- * a0 = pointer to boot info record
- * d0 = boot info offset
- * CONFIG_ATARI
- * a0 = address of SCC
- * a1 = Liobase address/address of scc_initable
- * d0 = init data for serial port
- * CONFIG_MAC
- * a0 = address of SCC
- * a1 = address of scc_initable_mac
- * d0 = init data for serial port
- */
- #ifdef CONFIG_AMIGA
- #define SERIAL_DTR 7
- #define SERIAL_CNTRL CIABBASE+C_PRA
- is_not_amiga(1f)
- lea %pc@(L(custom)),%a0
- movel #-ZTWOBASE,%a0@
- bclr #SERIAL_DTR,SERIAL_CNTRL-ZTWOBASE
- get_bi_record BI_AMIGA_SERPER
- movew %a0@,CUSTOMBASE+C_SERPER-ZTWOBASE
- | movew #61,CUSTOMBASE+C_SERPER-ZTWOBASE
- 1:
- #endif
- #ifdef CONFIG_ATARI
- is_not_atari(4f)
- movel %pc@(L(iobase)),%a1
- #if defined(USE_PRINTER)
- bclr #0,%a1@(LSTMFP_IERB)
- bclr #0,%a1@(LSTMFP_DDR)
- moveb #LPSG_CONTROL,%a1@(LPSG_SELECT)
- moveb #0xff,%a1@(LPSG_WRITE)
- moveb #LPSG_IO_B,%a1@(LPSG_SELECT)
- clrb %a1@(LPSG_WRITE)
- moveb #LPSG_IO_A,%a1@(LPSG_SELECT)
- moveb %a1@(LPSG_READ),%d0
- bset #5,%d0
- moveb %d0,%a1@(LPSG_WRITE)
- #elif defined(USE_SCC)
- lea %a1@(LSCC_CTRL),%a0
- lea %pc@(L(scc_initable)),%a1
- 2: moveb %a1@+,%d0
- jmi 3f
- moveb %d0,%a0@
- moveb %a1@+,%a0@
- jra 2b
- 3: clrb %a0@
- #elif defined(USE_MFP)
- bclr #1,%a1@(LMFP_TSR)
- moveb #0x88,%a1@(LMFP_UCR)
- andb #0x70,%a1@(LMFP_TDCDR)
- moveb #2,%a1@(LMFP_TDDR)
- orb #1,%a1@(LMFP_TDCDR)
- bset #1,%a1@(LMFP_TSR)
- #endif
- jra L(serial_init_done)
- 4:
- #endif
- #ifdef CONFIG_MAC
- is_not_mac(L(serial_init_not_mac))
- #ifdef MAC_SERIAL_DEBUG
- #if !defined(MAC_USE_SCC_A) && !defined(MAC_USE_SCC_B)
- #define MAC_USE_SCC_B
- #endif
- #define mac_scc_cha_b_ctrl_offset 0x0
- #define mac_scc_cha_a_ctrl_offset 0x2
- #define mac_scc_cha_b_data_offset 0x4
- #define mac_scc_cha_a_data_offset 0x6
- #ifdef MAC_USE_SCC_A
- /* Initialize channel A */
- movel %pc@(L(mac_sccbase)),%a0
- lea %pc@(L(scc_initable_mac)),%a1
- 5: moveb %a1@+,%d0
- jmi 6f
- moveb %d0,%a0@(mac_scc_cha_a_ctrl_offset)
- moveb %a1@+,%a0@(mac_scc_cha_a_ctrl_offset)
- jra 5b
- 6:
- #endif /* MAC_USE_SCC_A */
- #ifdef MAC_USE_SCC_B
- /* Initialize channel B */
- #ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */
- movel %pc@(L(mac_sccbase)),%a0
- #endif /* MAC_USE_SCC_A */
- lea %pc@(L(scc_initable_mac)),%a1
- 7: moveb %a1@+,%d0
- jmi 8f
- moveb %d0,%a0@(mac_scc_cha_b_ctrl_offset)
- moveb %a1@+,%a0@(mac_scc_cha_b_ctrl_offset)
- jra 7b
- 8:
- #endif /* MAC_USE_SCC_B */
- #endif /* MAC_SERIAL_DEBUG */
- jra L(serial_init_done)
- L(serial_init_not_mac):
- #endif /* CONFIG_MAC */
- #ifdef CONFIG_Q40
- is_not_q40(2f)
- /* debug output goes into SRAM, so we don't do it unless requested
- - check for '%LX$' signature in SRAM */
- lea %pc@(q40_mem_cptr),%a1
- move.l #0xff020010,%a1@ /* must be inited - also used by debug=mem */
- move.l #0xff020000,%a1
- cmp.b #'%',%a1@
- bne 2f /*nodbg*/
- addq.w #4,%a1
- cmp.b #'L',%a1@
- bne 2f /*nodbg*/
- addq.w #4,%a1
- cmp.b #'X',%a1@
- bne 2f /*nodbg*/
- addq.w #4,%a1
- cmp.b #'$',%a1@
- bne 2f /*nodbg*/
- /* signature OK */
- lea %pc@(L(q40_do_debug)),%a1
- tas %a1@
- /*nodbg: q40_do_debug is 0 by default*/
- 2:
- #endif
- #ifdef CONFIG_APOLLO
- /* We count on the PROM initializing SIO1 */
- #endif
- #ifdef CONFIG_HP300
- /* We count on the boot loader initialising the UART */
- #endif
- L(serial_init_done):
- func_return serial_init
- /*
- * Output character on serial port.
- */
- func_start serial_putc,%d0/%d1/%a0/%a1
- movel ARG1,%d0
- cmpib #'\n',%d0
- jbne 1f
- /* A little safe recursion is good for the soul */
- serial_putc #'\r'
- 1:
- #ifdef CONFIG_AMIGA
- is_not_amiga(2f)
- andw #0x00ff,%d0
- oriw #0x0100,%d0
- movel %pc@(L(custom)),%a0
- movew %d0,%a0@(CUSTOMBASE+C_SERDAT)
- 1: movew %a0@(CUSTOMBASE+C_SERDATR),%d0
- andw #0x2000,%d0
- jeq 1b
- jra L(serial_putc_done)
- 2:
- #endif
- #ifdef CONFIG_MAC
- is_not_mac(5f)
- #ifdef MAC_SERIAL_DEBUG
- #ifdef MAC_USE_SCC_A
- movel %pc@(L(mac_sccbase)),%a1
- 3: btst #2,%a1@(mac_scc_cha_a_ctrl_offset)
- jeq 3b
- moveb %d0,%a1@(mac_scc_cha_a_data_offset)
- #endif /* MAC_USE_SCC_A */
- #ifdef MAC_USE_SCC_B
- #ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */
- movel %pc@(L(mac_sccbase)),%a1
- #endif /* MAC_USE_SCC_A */
- 4: btst #2,%a1@(mac_scc_cha_b_ctrl_offset)
- jeq 4b
- moveb %d0,%a1@(mac_scc_cha_b_data_offset)
- #endif /* MAC_USE_SCC_B */
- #endif /* MAC_SERIAL_DEBUG */
- jra L(serial_putc_done)
- 5:
- #endif /* CONFIG_MAC */
- #ifdef CONFIG_ATARI
- is_not_atari(4f)
- movel %pc@(L(iobase)),%a1
- #if defined(USE_PRINTER)
- 3: btst #0,%a1@(LSTMFP_GPIP)
- jne 3b
- moveb #LPSG_IO_B,%a1@(LPSG_SELECT)
- moveb %d0,%a1@(LPSG_WRITE)
- moveb #LPSG_IO_A,%a1@(LPSG_SELECT)
- moveb %a1@(LPSG_READ),%d0
- bclr #5,%d0
- moveb %d0,%a1@(LPSG_WRITE)
- nop
- nop
- bset #5,%d0
- moveb %d0,%a1@(LPSG_WRITE)
- #elif defined(USE_SCC)
- 3: btst #2,%a1@(LSCC_CTRL)
- jeq 3b
- moveb %d0,%a1@(LSCC_DATA)
- #elif defined(USE_MFP)
- 3: btst #7,%a1@(LMFP_TSR)
- jeq 3b
- moveb %d0,%a1@(LMFP_UDR)
- #endif
- jra L(serial_putc_done)
- 4:
- #endif /* CONFIG_ATARI */
- #ifdef CONFIG_MVME147
- is_not_mvme147(2f)
- 1: btst #2,M147_SCC_CTRL_A
- jeq 1b
- moveb %d0,M147_SCC_DATA_A
- jbra L(serial_putc_done)
- 2:
- #endif
- #ifdef CONFIG_MVME16x
- is_not_mvme16x(2f)
- /*
- * If the loader gave us a board type then we can use that to
- * select an appropriate output routine; otherwise we just use
- * the Bug code. If we haev to use the Bug that means the Bug
- * workspace has to be valid, which means the Bug has to use
- * the SRAM, which is non-standard.
- */
- moveml %d0-%d7/%a2-%a6,%sp@-
- movel vme_brdtype,%d1
- jeq 1f | No tag - use the Bug
- cmpi #VME_TYPE_MVME162,%d1
- jeq 6f
- cmpi #VME_TYPE_MVME172,%d1
- jne 5f
- /* 162/172; it's an SCC */
- 6: btst #2,M162_SCC_CTRL_A
- nop
- nop
- nop
- jeq 6b
- moveb #8,M162_SCC_CTRL_A
- nop
- nop
- nop
- moveb %d0,M162_SCC_CTRL_A
- jra 3f
- 5:
- /* 166/167/177; it's a CD2401 */
- moveb #0,M167_CYCAR
- moveb M167_CYIER,%d2
- moveb #0x02,M167_CYIER
- 7:
- btst #5,M167_PCSCCTICR
- jeq 7b
- moveb M167_PCTPIACKR,%d1
- moveb M167_CYLICR,%d1
- jeq 8f
- moveb #0x08,M167_CYTEOIR
- jra 7b
- 8:
- moveb %d0,M167_CYTDR
- moveb #0,M167_CYTEOIR
- moveb %d2,M167_CYIER
- jra 3f
- 1:
- moveb %d0,%sp@-
- trap #15
- .word 0x0020 /* TRAP 0x020 */
- 3:
- moveml %sp@+,%d0-%d7/%a2-%a6
- jbra L(serial_putc_done)
- 2:
- #endif /* CONFIG_MVME16x */
- #ifdef CONFIG_BVME6000
- is_not_bvme6000(2f)
- /*
- * The BVME6000 machine has a serial port ...
- */
- 1: btst #2,BVME_SCC_CTRL_A
- jeq 1b
- moveb %d0,BVME_SCC_DATA_A
- jbra L(serial_putc_done)
- 2:
- #endif
- #ifdef CONFIG_SUN3X
- is_not_sun3x(2f)
- movel %d0,-(%sp)
- movel 0xFEFE0018,%a1
- jbsr (%a1)
- addq #4,%sp
- jbra L(serial_putc_done)
- 2:
- #endif
- #ifdef CONFIG_Q40
- is_not_q40(2f)
- tst.l %pc@(L(q40_do_debug)) /* only debug if requested */
- beq 2f
- lea %pc@(q40_mem_cptr),%a1
- move.l %a1@,%a0
- move.b %d0,%a0@
- addq.l #4,%a0
- move.l %a0,%a1@
- jbra L(serial_putc_done)
- 2:
- #endif
- #ifdef CONFIG_APOLLO
- is_not_apollo(2f)
- movl %pc@(L(iobase)),%a1
- moveb %d0,%a1@(LTHRB0)
- 1: moveb %a1@(LSRB0),%d0
- andb #0x4,%d0
- beq 1b
- jbra L(serial_putc_done)
- 2:
- #endif
- #ifdef CONFIG_HP300
- is_not_hp300(3f)
- movl %pc@(L(iobase)),%a1
- addl %pc@(L(uartbase)),%a1
- movel %pc@(L(uart_scode)),%d1 /* Check the scode */
- jmi 3f /* Unset? Exit */
- cmpi #256,%d1 /* APCI scode? */
- jeq 2f
- 1: moveb %a1@(DCALSR),%d1 /* Output to DCA */
- andb #0x20,%d1
- beq 1b
- moveb %d0,%a1@(DCADATA)
- jbra L(serial_putc_done)
- 2: moveb %a1@(APCILSR),%d1 /* Output to APCI */
- andb #0x20,%d1
- beq 2b
- moveb %d0,%a1@(APCIDATA)
- jbra L(serial_putc_done)
- 3:
- #endif
-
- L(serial_putc_done):
- func_return serial_putc
- /*
- * Output a string.
- */
- func_start puts,%d0/%a0
- movel ARG1,%a0
- jra 2f
- 1:
- #ifdef CONSOLE
- console_putc %d0
- #endif
- #ifdef SERIAL_DEBUG
- serial_putc %d0
- #endif
- 2: moveb %a0@+,%d0
- jne 1b
- func_return puts
- /*
- * Output number in hex notation.
- */
- func_start putn,%d0-%d2
- putc ' '
- movel ARG1,%d0
- moveq #7,%d1
- 1: roll #4,%d0
- move %d0,%d2
- andb #0x0f,%d2
- addb #'0',%d2
- cmpb #'9',%d2
- jls 2f
- addb #'A'-('9'+1),%d2
- 2:
- #ifdef CONSOLE
- console_putc %d2
- #endif
- #ifdef SERIAL_DEBUG
- serial_putc %d2
- #endif
- dbra %d1,1b
- func_return putn
- #ifdef CONFIG_MAC
- /*
- * mac_serial_print
- *
- * This routine takes its parameters on the stack. It then
- * turns around and calls the internal routine. This routine
- * is used until the Linux console driver initializes itself.
- *
- * The calling parameters are:
- * void mac_serial_print(const char *str);
- *
- * This routine does NOT understand variable arguments only
- * simple strings!
- */
- ENTRY(mac_serial_print)
- moveml %d0/%a0,%sp@-
- #if 1
- move %sr,%sp@-
- ori #0x0700,%sr
- #endif
- movel %sp@(10),%a0 /* fetch parameter */
- jra 2f
- 1: serial_putc %d0
- 2: moveb %a0@+,%d0
- jne 1b
- #if 1
- move %sp@+,%sr
- #endif
- moveml %sp@+,%d0/%a0
- rts
- #endif /* CONFIG_MAC */
- #if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
- func_start set_leds,%d0/%a0
- movel ARG1,%d0
- #ifdef CONFIG_HP300
- is_not_hp300(1f)
- movel %pc@(L(iobase)),%a0
- moveb %d0,%a0@(0x1ffff)
- jra 2f
- #endif
- 1:
- #ifdef CONFIG_APOLLO
- movel %pc@(L(iobase)),%a0
- lsll #8,%d0
- eorw #0xff00,%d0
- moveb %d0,%a0@(LCPUCTRL)
- #endif
- 2:
- func_return set_leds
- #endif
- #ifdef CONSOLE
- /*
- * For continuity, see the data alignment
- * to which this structure is tied.
- */
- #define Lconsole_struct_cur_column 0
- #define Lconsole_struct_cur_row 4
- #define Lconsole_struct_num_columns 8
- #define Lconsole_struct_num_rows 12
- #define Lconsole_struct_left_edge 16
- #define Lconsole_struct_penguin_putc 20
- func_start console_init,%a0-%a4/%d0-%d7
- /*
- * Some of the register usage that follows
- * a0 = pointer to boot_info
- * a1 = pointer to screen
- * a2 = pointer to Lconsole_globals
- * d3 = pixel width of screen
- * d4 = pixel height of screen
- * (d3,d4) ~= (x,y) of a point just below
- * and to the right of the screen
- * NOT on the screen!
- * d5 = number of bytes per scan line
- * d6 = number of bytes on the entire screen
- */
- lea %pc@(L(console_globals)),%a2
- movel %pc@(L(mac_videobase)),%a1
- movel %pc@(L(mac_rowbytes)),%d5
- movel %pc@(L(mac_dimensions)),%d3 /* -> low byte */
- movel %d3,%d4
- swap %d4 /* -> high byte */
- andl #0xffff,%d3 /* d3 = screen width in pixels */
- andl #0xffff,%d4 /* d4 = screen height in pixels */
- movel %d5,%d6
- | subl #20,%d6
- mulul %d4,%d6 /* scan line bytes x num scan lines */
- divul #8,%d6 /* we'll clear 8 bytes at a time */
- moveq #-1,%d0 /* Mac_black */
- subq #1,%d6
- L(console_clear_loop):
- movel %d0,%a1@+
- movel %d0,%a1@+
- dbra %d6,L(console_clear_loop)
- /* Calculate font size */
- #if defined(FONT_8x8) && defined(CONFIG_FONT_8x8)
- lea %pc@(font_vga_8x8),%a0
- #elif defined(FONT_8x16) && defined(CONFIG_FONT_8x16)
- lea %pc@(font_vga_8x16),%a0
- #elif defined(FONT_6x11) && defined(CONFIG_FONT_6x11)
- lea %pc@(font_vga_6x11),%a0
- #elif defined(CONFIG_FONT_8x8) /* default */
- lea %pc@(font_vga_8x8),%a0
- #else /* no compiled-in font */
- lea 0,%a0
- #endif
- /*
- * At this point we make a shift in register usage
- * a1 = address of console_font pointer
- */
- lea %pc@(L(console_font)),%a1
- movel %a0,%a1@ /* store pointer to struct fbcon_font_desc in console_font */
- tstl %a0
- jeq 1f
- lea %pc@(L(console_font_data)),%a4
- movel %a0@(FONT_DESC_DATA),%d0
- subl #L(console_font),%a1
- addl %a1,%d0
- movel %d0,%a4@
- /*
- * Calculate global maxs
- * Note - we can use either an
- * 8 x 16 or 8 x 8 character font
- * 6 x 11 also supported
- */
- /* ASSERT: a0 = contents of Lconsole_font */
- movel %d3,%d0 /* screen width in pixels */
- divul %a0@(FONT_DESC_WIDTH),%d0 /* d0 = max num chars per row */
- movel %d4,%d1 /* screen height in pixels */
- divul %a0@(FONT_DESC_HEIGHT),%d1 /* d1 = max num rows */
- movel %d0,%a2@(Lconsole_struct_num_columns)
- movel %d1,%a2@(Lconsole_struct_num_rows)
- /*
- * Clear the current row and column
- */
- clrl %a2@(Lconsole_struct_cur_column)
- clrl %a2@(Lconsole_struct_cur_row)
- clrl %a2@(Lconsole_struct_left_edge)
- /*
- * Initialization is complete
- */
- 1:
- func_return console_init
- func_start console_put_stats,%a0/%d7
- /*
- * Some of the register usage that follows
- * a0 = pointer to boot_info
- * d7 = value of boot_info fields
- */
- puts "\nMacLinux\n\n"
- #ifdef SERIAL_DEBUG
- puts " vidaddr:"
- putn %pc@(L(mac_videobase)) /* video addr. */
- puts "\n _stext:"
- lea %pc@(_stext),%a0
- putn %a0
- puts "\nbootinfo:"
- lea %pc@(_end),%a0
- putn %a0
- puts "\ncpuid:"
- putn %pc@(L(cputype))
- putc '\n'
- #ifdef MAC_SERIAL_DEBUG
- putn %pc@(L(mac_sccbase))
- putc '\n'
- #endif
- # if defined(MMU_PRINT)
- jbsr mmu_print_machine_cpu_types
- # endif /* MMU_PRINT */
- #endif /* SERIAL_DEBUG */
- func_return console_put_stats
- #ifdef CONSOLE_PENGUIN
- func_start console_put_penguin,%a0-%a1/%d0-%d7
- /*
- * Get 'that_penguin' onto the screen in the upper right corner
- * penguin is 64 x 74 pixels, align against right edge of screen
- */
- lea %pc@(L(mac_dimensions)),%a0
- movel %a0@,%d0
- andil #0xffff,%d0
- subil #64,%d0 /* snug up against the right edge */
- clrl %d1 /* start at the top */
- movel #73,%d7
- lea %pc@(L(that_penguin)),%a1
- L(console_penguin_row):
- movel #31,%d6
- L(console_penguin_pixel_pair):
- moveb %a1@,%d2
- lsrb #4,%d2
- console_plot_pixel %d0,%d1,%d2
- addq #1,%d0
- moveb %a1@+,%d2
- console_plot_pixel %d0,%d1,%d2
- addq #1,%d0
- dbra %d6,L(console_penguin_pixel_pair)
- subil #64,%d0
- addq #1,%d1
- dbra %d7,L(console_penguin_row)
- func_return console_put_penguin
- /* include penguin bitmap */
- L(that_penguin):
- #include "../mac/mac_penguin.S"
- #endif
- /*
- * Calculate source and destination addresses
- * output a1 = dest
- * a2 = source
- */
- func_start console_scroll,%a0-%a4/%d0-%d7
- lea %pc@(L(mac_videobase)),%a0
- movel %a0@,%a1
- movel %a1,%a2
- lea %pc@(L(mac_rowbytes)),%a0
- movel %a0@,%d5
- movel %pc@(L(console_font)),%a0
- tstl %a0
- jeq 1f
- mulul %a0@(FONT_DESC_HEIGHT),%d5 /* account for # scan lines per character */
- addal %d5,%a2
- /*
- * Get dimensions
- */
- lea %pc@(L(mac_dimensions)),%a0
- movel %a0@,%d3
- movel %d3,%d4
- swap %d4
- andl #0xffff,%d3 /* d3 = screen width in pixels */
- andl #0xffff,%d4 /* d4 = screen height in pixels */
- /*
- * Calculate number of bytes to move
- */
- lea %pc@(L(mac_rowbytes)),%a0
- movel %a0@,%d6
- movel %pc@(L(console_font)),%a0
- subl %a0@(FONT_DESC_HEIGHT),%d4 /* we're not scrolling the top row! */
- mulul %d4,%d6 /* scan line bytes x num scan lines */
- divul #32,%d6 /* we'll move 8 longs at a time */
- subq #1,%d6
- L(console_scroll_loop):
- movel %a2@+,%a1@+
- movel %a2@+,%a1@+
- movel %a2@+,%a1@+
- movel %a2@+,%a1@+
- movel %a2@+,%a1@+
- movel %a2@+,%a1@+
- movel %a2@+,%a1@+
- movel %a2@+,%a1@+
- dbra %d6,L(console_scroll_loop)
- lea %pc@(L(mac_rowbytes)),%a0
- movel %a0@,%d6
- movel %pc@(L(console_font)),%a0
- mulul %a0@(FONT_DESC_HEIGHT),%d6 /* scan line bytes x font height */
- divul #32,%d6 /* we'll move 8 words at a time */
- subq #1,%d6
- moveq #-1,%d0
- L(console_scroll_clear_loop):
- movel %d0,%a1@+
- movel %d0,%a1@+
- movel %d0,%a1@+
- movel %d0,%a1@+
- movel %d0,%a1@+
- movel %d0,%a1@+
- movel %d0,%a1@+
- movel %d0,%a1@+
- dbra %d6,L(console_scroll_clear_loop)
- 1:
- func_return console_scroll
- func_start console_putc,%a0/%a1/%d0-%d7
- is_not_mac(L(console_exit))
- tstl %pc@(L(console_font))
- jeq L(console_exit)
- /* Output character in d7 on console.
- */
- movel ARG1,%d7
- cmpib #'\n',%d7
- jbne 1f
- /* A little safe recursion is good for the soul */
- console_putc #'\r'
- 1:
- lea %pc@(L(console_globals)),%a0
- cmpib #10,%d7
- jne L(console_not_lf)
- movel %a0@(Lconsole_struct_cur_row),%d0
- addil #1,%d0
- movel %d0,%a0@(Lconsole_struct_cur_row)
- movel %a0@(Lconsole_struct_num_rows),%d1
- cmpl %d1,%d0
- jcs 1f
- subil #1,%d0
- movel %d0,%a0@(Lconsole_struct_cur_row)
- console_scroll
- 1:
- jra L(console_exit)
- L(console_not_lf):
- cmpib #13,%d7
- jne L(console_not_cr)
- clrl %a0@(Lconsole_struct_cur_column)
- jra L(console_exit)
- L(console_not_cr):
- cmpib #1,%d7
- jne L(console_not_home)
- clrl %a0@(Lconsole_struct_cur_row)
- clrl %a0@(Lconsole_struct_cur_column)
- jra L(console_exit)
- /*
- * At this point we know that the %d7 character is going to be
- * rendered on the screen. Register usage is -
- * a0 = pointer to console globals
- * a1 = font data
- * d0 = cursor column
- * d1 = cursor row to draw the character
- * d7 = character number
- */
- L(console_not_home):
- movel %a0@(Lconsole_struct_cur_column),%d0
- addql #1,%a0@(Lconsole_struct_cur_column)
- movel %a0@(Lconsole_struct_num_columns),%d1
- cmpl %d1,%d0
- jcs 1f
- console_putc #'\n' /* recursion is OK! */
- 1:
- movel %a0@(Lconsole_struct_cur_row),%d1
- /*
- * At this point we make a shift in register usage
- * a0 = address of pointer to font data (fbcon_font_desc)
- */
- movel %pc@(L(console_font)),%a0
- movel %pc@(L(console_font_data)),%a1 /* Load fbcon_font_desc.data into a1 */
- andl #0x000000ff,%d7
- /* ASSERT: a0 = contents of Lconsole_font */
- mulul %a0@(FONT_DESC_HEIGHT),%d7 /* d7 = index into font data */
- addl %d7,%a1 /* a1 = points to char image */
- /*
- * At this point we make a shift in register usage
- * d0 = pixel coordinate, x
- * d1 = pixel coordinate, y
- * d2 = (bit 0) 1/0 for white/black (!) pixel on screen
- * d3 = font scan line data (8 pixels)
- * d6 = count down for the font's pixel width (8)
- * d7 = count down for the font's pixel count in height
- */
- /* ASSERT: a0 = contents of Lconsole_font */
- mulul %a0@(FONT_DESC_WIDTH),%d0
- mulul %a0@(FONT_DESC_HEIGHT),%d1
- movel %a0@(FONT_DESC_HEIGHT),%d7 /* Load fbcon_font_desc.height into d7 */
- subq #1,%d7
- L(console_read_char_scanline):
- moveb %a1@+,%d3
- /* ASSERT: a0 = contents of Lconsole_font */
- movel %a0@(FONT_DESC_WIDTH),%d6 /* Load fbcon_font_desc.width into d6 */
- subql #1,%d6
- L(console_do_font_scanline):
- lslb #1,%d3
- scsb %d2 /* convert 1 bit into a byte */
- console_plot_pixel %d0,%d1,%d2
- addq #1,%d0
- dbra %d6,L(console_do_font_scanline)
- /* ASSERT: a0 = contents of Lconsole_font */
- subl %a0@(FONT_DESC_WIDTH),%d0
- addq #1,%d1
- dbra %d7,L(console_read_char_scanline)
- L(console_exit):
- func_return console_putc
- /*
- * Input:
- * d0 = x coordinate
- * d1 = y coordinate
- * d2 = (bit 0) 1/0 for white/black (!)
- * All registers are preserved
- */
- func_start console_plot_pixel,%a0-%a1/%d0-%d4
- movel %pc@(L(mac_videobase)),%a1
- movel %pc@(L(mac_videodepth)),%d3
- movel ARG1,%d0
- movel ARG2,%d1
- mulul %pc@(L(mac_rowbytes)),%d1
- movel ARG3,%d2
- /*
- * Register usage:
- * d0 = x coord becomes byte offset into frame buffer
- * d1 = y coord
- * d2 = black or white (0/1)
- * d3 = video depth
- * d4 = temp of x (d0) for many bit depths
- */
- L(test_1bit):
- cmpb #1,%d3
- jbne L(test_2bit)
- movel %d0,%d4 /* we need the low order 3 bits! */
- divul #8,%d0
- addal %d0,%a1
- addal %d1,%a1
- andb #7,%d4
- eorb #7,%d4 /* reverse the x-coordinate w/ screen-bit # */
- andb #1,%d2
- jbne L(white_1)
- bsetb %d4,%a1@
- jbra L(console_plot_pixel_exit)
- L(white_1):
- bclrb %d4,%a1@
- jbra L(console_plot_pixel_exit)
- L(test_2bit):
- cmpb #2,%d3
- jbne L(test_4bit)
- movel %d0,%d4 /* we need the low order 2 bits! */
- divul #4,%d0
- addal %d0,%a1
- addal %d1,%a1
- andb #3,%d4
- eorb #3,%d4 /* reverse the x-coordinate w/ screen-bit # */
- lsll #1,%d4 /* ! */
- andb #1,%d2
- jbne L(white_2)
- bsetb %d4,%a1@
- addq #1,%d4
- bsetb %d4,%a1@
- jbra L(console_plot_pixel_exit)
- L(white_2):
- bclrb %d4,%a1@
- addq #1,%d4
- bclrb %d4,%a1@
- jbra L(console_plot_pixel_exit)
- L(test_4bit):
- cmpb #4,%d3
- jbne L(test_8bit)
- movel %d0,%d4 /* we need the low order bit! */
- divul #2,%d0
- addal %d0,%a1
- addal %d1,%a1
- andb #1,%d4
- eorb #1,%d4
- lsll #2,%d4 /* ! */
- andb #1,%d2
- jbne L(white_4)
- bsetb %d4,%a1@
- addq #1,%d4
- bsetb %d4,%a1@
- addq #1,%d4
- bsetb %d4,%a1@
- addq #1,%d4
- bsetb %d4,%a1@
- jbra L(console_plot_pixel_exit)
- L(white_4):
- bclrb %d4,%a1@
- addq #1,%d4
- bclrb %d4,%a1@
- addq #1,%d4
- bclrb %d4,%a1@
- addq #1,%d4
- bclrb %d4,%a1@
- jbra L(console_plot_pixel_exit)
- L(test_8bit):
- cmpb #8,%d3
- jbne L(test_16bit)
- addal %d0,%a1
- addal %d1,%a1
- andb #1,%d2
- jbne L(white_8)
- moveb #0xff,%a1@
- jbra L(console_plot_pixel_exit)
- L(white_8):
- clrb %a1@
- jbra L(console_plot_pixel_exit)
- L(test_16bit):
- cmpb #16,%d3
- jbne L(console_plot_pixel_exit)
- addal %d0,%a1
- addal %d0,%a1
- addal %d1,%a1
- andb #1,%d2
- jbne L(white_16)
- clrw %a1@
- jbra L(console_plot_pixel_exit)
- L(white_16):
- movew #0x0fff,%a1@
- jbra L(console_plot_pixel_exit)
- L(console_plot_pixel_exit):
- func_return console_plot_pixel
- #endif /* CONSOLE */
- #if 0
- /*
- * This is some old code lying around. I don't believe
- * it's used or important anymore. My guess is it contributed
- * to getting to this point, but it's done for now.
- * It was still in the 2.1.77 head.S, so it's still here.
- * (And still not used!)
- */
- L(showtest):
- moveml %a0/%d7,%sp@-
- puts "A="
- putn %a1
- .long 0xf0119f15 | ptestr #5,%a1@,#7,%a0
- puts "DA="
- putn %a0
- puts "D="
- putn %a0@
- puts "S="
- lea %pc@(L(mmu)),%a0
- .long 0xf0106200 | pmove %psr,%a0@
- clrl %d7
- movew %a0@,%d7
- putn %d7
- putc '\n'
- moveml %sp@+,%a0/%d7
- rts
- #endif /* 0 */
- __INITDATA
- .align 4
- #if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
- defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
- L(custom):
- L(iobase):
- .long 0
- #endif
- #if defined(CONSOLE)
- L(console_globals):
- .long 0 /* cursor column */
- .long 0 /* cursor row */
- .long 0 /* max num columns */
- .long 0 /* max num rows */
- .long 0 /* left edge */
- .long 0 /* mac putc */
- L(console_font):
- .long 0 /* pointer to console font (struct font_desc) */
- L(console_font_data):
- .long 0 /* pointer to console font data */
- #endif /* CONSOLE */
- #if defined(MMU_PRINT)
- L(mmu_print_data):
- .long 0 /* valid flag */
- .long 0 /* start logical */
- .long 0 /* next logical */
- .long 0 /* start physical */
- .long 0 /* next physical */
- #endif /* MMU_PRINT */
- L(cputype):
- .long 0
- L(mmu_cached_pointer_tables):
- .long 0
- L(mmu_num_pointer_tables):
- .long 0
- L(phys_kernel_start):
- .long 0
- L(kernel_end):
- .long 0
- L(memory_start):
- .long 0
- L(kernel_pgdir_ptr):
- .long 0
- L(temp_mmap_mem):
- .long 0
- #if defined (CONFIG_MVME147)
- M147_SCC_CTRL_A = 0xfffe3002
- M147_SCC_DATA_A = 0xfffe3003
- #endif
- #if defined (CONFIG_MVME16x)
- M162_SCC_CTRL_A = 0xfff45005
- M167_CYCAR = 0xfff450ee
- M167_CYIER = 0xfff45011
- M167_CYLICR = 0xfff45026
- M167_CYTEOIR = 0xfff45085
- M167_CYTDR = 0xfff450f8
- M167_PCSCCTICR = 0xfff4201e
- M167_PCTPIACKR = 0xfff42025
- #endif
- #if defined (CONFIG_BVME6000)
- BVME_SCC_CTRL_A = 0xffb0000b
- BVME_SCC_DATA_A = 0xffb0000f
- #endif
- #if defined(CONFIG_MAC)
- L(mac_booter_data):
- .long 0
- L(mac_videobase):
- .long 0
- L(mac_videodepth):
- .long 0
- L(mac_dimensions):
- .long 0
- L(mac_rowbytes):
- .long 0
- #ifdef MAC_SERIAL_DEBUG
- L(mac_sccbase):
- .long 0
- #endif /* MAC_SERIAL_DEBUG */
- #endif
- #if defined (CONFIG_APOLLO)
- LSRB0 = 0x10412
- LTHRB0 = 0x10416
- LCPUCTRL = 0x10100
- #endif
- #if defined(CONFIG_HP300)
- DCADATA = 0x11
- DCALSR = 0x1b
- APCIDATA = 0x00
- APCILSR = 0x14
- L(uartbase):
- .long 0
- L(uart_scode):
- .long -1
- #endif
- __FINIT
- .data
- .align 4
- availmem:
- .long 0
- m68k_pgtable_cachemode:
- .long 0
- m68k_supervisor_cachemode:
- .long 0
- #if defined(CONFIG_MVME16x)
- mvme_bdid:
- .long 0,0,0,0,0,0,0,0
- #endif
- #if defined(CONFIG_Q40)
- q40_mem_cptr:
- .long 0
- L(q40_do_debug):
- .long 0
- #endif
|