1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868 |
- /* -*- 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
- ** 1999/02/11 Richard Zidlicky: added Q40 support (initial version 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
- * position 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 / #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 autoconf.h.
- *
- * CONSOLE_DEBUG: Only supports a Mac frame buffer but could easily be
- * extended 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.
- *
- * 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_USE_SCC_A: Use SCC port A (modem) for serial debug.
- * MAC_USE_SCC_B: Use SCC port B (printer) for serial debug.
- */
- #include <linux/linkage.h>
- #include <linux/init.h>
- #include <asm/bootinfo.h>
- #include <asm/bootinfo-amiga.h>
- #include <asm/bootinfo-atari.h>
- #include <asm/bootinfo-hp300.h>
- #include <asm/bootinfo-mac.h>
- #include <asm/bootinfo-q40.h>
- #include <asm/bootinfo-vme.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>
- #endif
- #ifdef CONFIG_EARLY_PRINTK
- # define SERIAL_DEBUG
- # if defined(CONFIG_MAC) && defined(CONFIG_FONT_SUPPORT)
- # define CONSOLE_DEBUG
- # endif
- #endif
- #undef MMU_PRINT
- #undef MMU_NOCACHE_KERNEL
- #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_init_mapped_size
- .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_penguin
- func_define console_plot_pixel,3
- func_define console_scroll
- .macro putc ch
- #if defined(CONSOLE_DEBUG) || defined(SERIAL_DEBUG)
- pea \ch
- #endif
- #ifdef CONSOLE_DEBUG
- func_call console_putc
- #endif
- #ifdef SERIAL_DEBUG
- func_call serial_putc
- #endif
- #if defined(CONSOLE_DEBUG) || 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_DEBUG) || 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
- __HEAD
- 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@
- get_bi_record BI_MAC_SCCBASE
- lea %pc@(L(mac_sccbase)),%a1
- movel %a0@,%a1@
- 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_DEBUG
- console_init
- # ifdef CONFIG_LOGO
- console_put_penguin
- # endif /* CONFIG_LOGO */
- # endif /* CONSOLE_DEBUG */
- 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, 8, or 16 MB of kernel code & data
- */
- get_bi_record BI_MEMCHUNK
- movel %a0@(4),%d0
- movel #16*1024*1024,%d1
- cmpl %d0,%d1
- jls 1f
- lsrl #1,%d1
- cmpl %d0,%d1
- jls 1f
- lsrl #1,%d1
- 1:
- lea %pc@(m68k_init_mapped_size),%a0
- movel %d1,%a0@
- mmu_map #PAGE_OFFSET,%pc@(L(phys_kernel_start)),%d1,\
- %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 up to 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 up to 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 up to logical 0xf000.0000
- */
- mmu_map #0xf0000000,#0,#0x02000000,#_PAGE_NOCACHE030
- jbra L(mmu_init_done)
- 1:
- /*
- * 040: Map the 16Meg range physical 0x0 up to 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)
- #ifdef CONSOLE_DEBUG
- movel %pc@(L(phys_kernel_start)),%d0
- subl #PAGE_OFFSET,%d0
- subl %d0,L(console_font)
- subl %d0,L(console_font_data)
- #endif
- orl #0x50000000,L(mac_sccbase)
- 1:
- #endif
- #ifdef CONFIG_HP300
- is_not_hp300(2f)
- /*
- * 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
- * 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"
- 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
- /* You may define either or both of these. */
- #define MAC_USE_SCC_A /* Modem port */
- #define MAC_USE_SCC_B /* Printer port */
- #if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
- /* Initialisation table for SCC with 3.6864 MHz PCLK */
- L(scc_initable_mac):
- .byte 4,0x44 /* x16, 1 stopbit, no parity */
- .byte 3,0xc0 /* receiver: 8 bpc */
- .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
- .byte 10,0 /* NRZ */
- .byte 11,0x50 /* use baud rate generator */
- .byte 12,1,13,0 /* 38400 baud */
- .byte 14,1 /* Baud rate generator enable */
- .byte 3,0xc1 /* enable receiver */
- .byte 5,0xea /* enable transmitter */
- .byte -1
- .even
- #endif
- #endif /* CONFIG_MAC */
- #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)
- /* Initialisation table for SCC with 7.9872 MHz PCLK */
- /* PCLK == 8.0539 gives baud == 9680.1 */
- L(scc_initable_atari):
- .byte 4,0x44 /* x16, 1 stopbit, no parity */
- .byte 3,0xc0 /* receiver: 8 bpc */
- .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
- .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
- */
- 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_atari
- * 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_A) || defined(USE_SCC_B)
- lea %a1@(LSCC_CTRL),%a0
- /* Reset SCC register pointer */
- moveb %a0@,%d0
- /* Reset SCC device: write register pointer then register value */
- moveb #9,%a0@
- moveb #0xc0,%a0@
- /* Wait for 5 PCLK cycles, which is about 63 CPU cycles */
- /* 5 / 7.9872 MHz = approx. 0.63 us = 63 / 100 MHz */
- movel #32,%d0
- 2:
- subq #1,%d0
- jne 2b
- /* Initialize channel */
- lea %pc@(L(scc_initable_atari)),%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))
- #if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
- #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
- movel %pc@(L(mac_sccbase)),%a0
- /* Reset SCC register pointer */
- moveb %a0@(mac_scc_cha_a_ctrl_offset),%d0
- /* Reset SCC device: write register pointer then register value */
- moveb #9,%a0@(mac_scc_cha_a_ctrl_offset)
- moveb #0xc0,%a0@(mac_scc_cha_a_ctrl_offset)
- /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */
- /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */
- movel #35,%d0
- 5:
- subq #1,%d0
- jne 5b
- #endif
- #ifdef MAC_USE_SCC_A
- /* Initialize channel A */
- 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 */
- 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 */
- 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_MVME16x
- is_not_mvme16x(L(serial_init_not_mvme16x))
- moveb #0x10,M167_PCSCCMICR
- moveb #0x10,M167_PCSCCTICR
- moveb #0x10,M167_PCSCCRICR
- jra L(serial_init_done)
- L(serial_init_not_mvme16x):
- #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)
- #if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
- movel %pc@(L(mac_sccbase)),%a1
- #endif
- #ifdef MAC_USE_SCC_A
- 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
- 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 */
- 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_A) || defined(USE_SCC_B)
- 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 have 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_DEBUG
- 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_DEBUG
- console_putc %d2
- #endif
- #ifdef SERIAL_DEBUG
- serial_putc %d2
- #endif
- dbra %d1,1b
- func_return putn
- #ifdef CONFIG_EARLY_PRINTK
- /*
- * This routine takes its parameters on the stack. It then
- * turns around and calls the internal routines. This routine
- * is used by the boot console.
- *
- * The calling parameters are:
- * void debug_cons_nputs(const char *str, unsigned length)
- *
- * This routine does NOT understand variable arguments only
- * simple strings!
- */
- ENTRY(debug_cons_nputs)
- moveml %d0/%d1/%a0,%sp@-
- movew %sr,%sp@-
- ori #0x0700,%sr
- movel %sp@(18),%a0 /* fetch parameter */
- movel %sp@(22),%d1 /* fetch parameter */
- jra 2f
- 1:
- #ifdef CONSOLE_DEBUG
- console_putc %d0
- #endif
- #ifdef SERIAL_DEBUG
- serial_putc %d0
- #endif
- subq #1,%d1
- 2: jeq 3f
- moveb %a0@+,%d0
- jne 1b
- 3:
- movew %sp@+,%sr
- moveml %sp@+,%d0/%d1/%a0
- rts
- #endif /* CONFIG_EARLY_PRINTK */
- #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_DEBUG
- /*
- * 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
- 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 console_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
- #ifdef CONFIG_LOGO
- 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_DEBUG */
- __INITDATA
- .align 4
- m68k_init_mapped_size:
- .long 0
- #if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
- defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
- L(custom):
- L(iobase):
- .long 0
- #endif
- #ifdef CONSOLE_DEBUG
- 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 */
- 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_DEBUG */
- #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_PCSCCMICR = 0xfff4201d
- M167_PCSCCTICR = 0xfff4201e
- M167_PCSCCRICR = 0xfff4201f
- 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_videobase):
- .long 0
- L(mac_videodepth):
- .long 0
- L(mac_dimensions):
- .long 0
- L(mac_rowbytes):
- .long 0
- L(mac_sccbase):
- .long 0
- #endif /* CONFIG_MAC */
- #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
|