Flameman/tutorm68k

For more interesting projects done by Flameman, be sure to checkout his project index

http://www.webalice.it/mr.ddc/machine/m68000-my-boad.jpg



this board
 * has 68010
 * 2 acia 6850
 * 1 pit 68230
 * 2 ram ??? kb
 * 2 rom ??? kb
 * motorola tutor firmware
 * board size: 250x130 mm
 * case size: 285x295 mm

case has been build from "IBM 3197 Terminal Logic Base"

picoMMU
http://www.appuntidigitali.it/4262/virtualizzazione-a-basso-costo-col-motorola-68010/

http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&thread.id=7736

IBM le suonerebbe mostrando quanti anni fosse avanti
si scopre che nel 1967 IBM mentre rilasciava il primo 360/91 gia’ introduceva il concetto di “pipeline” (inventato da R.Tomasulo)
 * parliamo di “pipeline”?

e il 360, con tempo medio d’accesso di 80 nano secondi, introduceva anche quella ben 10-12 volte piu’ veloce della standard magnetic core memory
 * parliamo di “cache memory” ?

scopriamo che nel 1970 l’evoluzione dei sistemi 360 si distingue per la gestione della memoria virtuale, fatto decisamente inedito. La famiglia 370 portera’ negli nni a venire molti tecnici al di fuori del mondo IBM a denigrare la bassa capacita’ di memoria di alcuni sistemi IBM rispetto ad altre marche, non conoscendo le funzioni straordinarie della gestione della memoria virtuale. Se per quei tempi il meccanismo poteva essere “visionario” i fatti “moderni” hanno incontroverbilmente dimostrato quanto costoro errassero gravemente: per poter funzionare, un programma, deve essere caricato nella memoria centrale del computer. Se la memoria e’ troppo poca il programma non gira.
 * parliamo di “memoria virtuale” ?

Nei sistemi mainframe e mini IBM il problema e’ stato risolto con la memoria virtuale, che consente una gestione totalmente automatica di carico/scarico di parti di programma, non richieste in un determinato momento, da disco a memoria centrale.

Ma non solo!, una altra funzione molto importante e’ il “virtual storage” (come lo chiama IBM), che consente di caricare in memoria parti di dati di cui il sistema prevede il prossimo utilizzo. In questo modo la macchina non deve chiedere frequentemente i dati che le servono, perche’ questi si trovano già disponibili nella memoria centrale. In sostanza il sistema vede memoria centrale e memorie di massa come un tutt’uno.

la rivoluzione, quella vera, e’ nel 1978 ovvero 2 anni prima che il prototipo del PC IBM vienise estremamemente semplificato, ridisegnato da Donald Estridge, in modo che potesse entrare negli stipendi della gente comune, e poi spedito in Microsoft, quella piccola azienda che non conosceva nessuno, ma che vendeva BASIC per macchine come l’Altair 8800, e che per IBM avrebbe invece dovuto confezionare quel sottile ed innocente sistema operativo DOS capace di far girare applicazioni assai modeste, senza pretese di affidabilita’, scalabilita’, e quantaltro ai tempi NON necessitava di timesharing, multitasking, etc, e quanto era stava per essere annunciato.

Prima di svelarlo, un attimo di suspense … per ricordare che il core business IBM ha sempre ruotato nel gestire in modo estremamente sicuro ed efficiente una rete aziendale:applicazioni multiutente di buon livello, con ampio ventaglio per tutti i settori aziendali, oltre che piena coperatura anche per le esigenze di enti pubblici.

Questi sono gli obiettivi che portarono la vera grande immensa rivoluzione segnata nel 1978 dal lancio del sistema S/38, pensato per abbattere il limite imposto dalla memoria, creando un continuo unico tra memoria e disco era nata la memoria virtuale, l’abbiamo gia’ detto, ma non solo! Veniva anche introdotto anche il concetto di oggetti incapsulati (le fondamenta della sicurezza, quella vera, in multiutenza blindata) e per finire, veniva introdotto anche il concetto di macchina virtuale, un meccanismo capace di rendere indipendente il layer applicativo dalla substrato hardware sottostante

shock: era francamente troppo meraviglioso!

tanto che nel ‘78 quella macchina (e il suo sistema operativo) era dannatamente difficile da comprendere, ma non solo per i clienti parecchio sbigottiti, ma sopratutto per gli sviluppatori che preferirono restare coi piedi per terra

l’esperienza non segno’ tante vendite ma getto’ le fondamenta dei successivi AS400

xke’ l’obbiettivo primario era, come sempre, rendere il sistema ottimizzato per elaborare transazioni, tante transazioni, tanto, ma proprio tanto IO !

i successivi sistemi operativi si presentarono omogenei e completi, ma la grossa novita’ stava nel fatto che il software al lato applicativo, cioe’ quello vicino al cliente, era stranamente indipendente dalle evoluzioni hardware!

Pazzesco ! Del resto l’obbietto “macchina virtuale” era centrato al punto che offriva compreso nel prezzo un database relazionale integrato ai più bassi livelli di macchina!

e non solo! gran parte della virtualizzazione rendava davvero possibile operare con tecnologia Object Oriented (e siamo solo nel 1988!), in modo ampiamente scalabile, lavorando in multiprocessing, e, cosa fodamentale: progettato garantendo la massima sicurezza e riservatezza a causa della sua struttura interna (la tipicizzazione quasi richiama i concetti moderni introdotti da SUN con java)

Gli AS400 hanno cambiato parecchie volte l’archietettura delle cpu degli strati harware + bassi, questo la dice lunga non solo sulla virtualizzazione ma anche sulla filosofia (non solo) IBM circa la struttura dell’architettura di un sistema di elaborazione: ovvero che non debba gravitare completamente e solamente sulla velocita’ del processore (o dei processori) “centrali”, non devono premiare SOLO la cpu (central process …), anzi al contrario, questi sistemi dispongono diversi processori specializzati in vari compiti per ottimizzare tutto il flusso di elaborazione degli input e degli output: sono macchine per elaborare dati e costruire informazioni utili in ambito aziendale, quindi vale la regola del “tanto I/O, poco calcolo”, che e’, come detto, l’opposto di quanto serve in un pc dedicato, per esempio, ad un gioco o ad un calcolo matematico o alla grafica.

Ora, arrivando circa ai nostri anni, nel 2000 IBM presenta una nuova serie di server AS/400, chiamti “iSeries”, di classe paragonabile ai mainframe per affidabilita’ e scalabilita’, diffondendo il supporto agli open standard per lo sviluppo di nuove applicazioni e introducendo il concetto di potenza su richiesta (capacity on demand) utilissima per superare nelle aziende i picchi di necessita’ elaborativa, senza per questo ricorrere a macchine piu’ potenti.

Fra le feature e’ possibile partizionare i dischi (LPAR) in modo da rendere disponibili parallelamente sistemi operativi diversi, ma tutti sotto la garanzia di affidabilità dell’hardware ormai ultrasperimentato.

Nel 2003 arrivano anche i server serie z, fra cui lo z990 che vanta features sbalorditive: partendo dalla tecnologia del modulo di CPU, realizzato in MultiChipModule, ai risultati, pari a 9.000 mips, 13 miliardi di transazioni al giorno, l’affidabilita’ meno di 5 minuti di downtime all’anno, e le possibilita’ di distribuire dinamicamente i workload all’interno della macchina in base alle priorita’ stabilite dal cliente.

idee che portano alla picoMMU
con 68010 iniziano le possibilita' di virtualizzare: ai tempi venne sfornata una segment MMU mc68451, oggi si trova solo doc cartacea della paged MMU mc68851: nel mio caso non voglio impiegarla, troppo complessa, e quel punto impigherei un 68030 con MMU, una versione semplificata proprio della mc68851, gia’ integrata, xke' francaemente per il kernel semplice che ho in mente una paged MMU e’ esagerata

quindi penso che, per la mia m68010 board, mi sintetizzero’ qualcosa di molti simil a quanto fu fatto per Apple Lisa

ovvero qualcosa che soddisfi l’equazione

if (!S) PA=(VA && MASK) + DISPLACEMENT else (!S) PA=VA

Physical Addrss Virtual Address

Praticamente un sistema di traslazione a un solo livello da VA a PA. Estremamente semplice.

Beh, certo, dipende sempre da quello che vuoi farci. Se il kernel è “semplice” (non so com’è strutturato) come dici, può andare bene.

esatto! e cosi’ posso anche rilassarne l’implementazione in VHDL, sia per complessita’, sia per risorse richieste

fra l’altro ho spulciato la documentazione tecnica di Apple Lisa scoprendo che anche la loro MMU usava un approccio simile: PA=VA + displacement!

ora, considerando che una unita’ segmente MMU mc68451 riesce a gestire solo 32 Task, considerando che aggiunge 4 cicli di clock per la traduzione, che necessita esclusivamente di un 68010, e considerando che 32Task indirizzabili rischiano di essere oggettivamente pochi al punto che sarebbe auspicabile porre almeno un paio di mc68451 in parallelo (cosa prevista, dunque fattibile) per scalarne il numero di Task indirizzabili (2×32): beh, visto che in embedded cio’ che si vende e’ 68ec/hc000, visto che della mc68451 non c’e’ documentazione (ne fornitura), ma che sopratutto queste MMU sono in fin dei conti di compromesso circuitale tanto quanto algoritmico: ma allora xke’ dunque non sintetizzare qualcosa di specifico, che riutilizzabile con core 68000 in commercio, e che concorra a semplificare ulteriormente l’intero progetto ?

detto fatto, e il picoKernel ringrazia

Immaginavo, ma io mi chiedo: non conviene buttarsi direttamente su soluzioni embedded che abbiano già integrata una MMU (magari più semplice, come quella presente nel 68030 o nel 68060)? Così si eviterebbe di dover progettare parte di una circuiteria, per quanto sia di gran lunga più semplice il modello PA=VA+Offset.

Non sono un esperto di sistemi embedded, per cui non riesco a capire quali vantaggi possa portare una soluzione custom (che richiede maggiori costi di progettazione, e relativa perdita di tempo) rispetto a una preconfezionata. Mi sfugge il dominio applicativo nel suo complesso.

in campo embedded si diventa maniacali, meno codice si scrive meglio e’ (a volte meno memoria dinamica, malloc per capirci, si usa, meglio e’)

ne consegue che si tende a fare sistemi con task statici, memoria statica, poco codice e molto diretto al “problem solution”: questo xke’ impiegare una MMU (paged oriented) costa MOLTO in termini di codice!

nel mio caso, a maggior ragione, il problem e’ … general purpose avocation, cioe’ hobby & learn for research

sicche’ il primo punto e’ stato capire le differenze fra una segment MMU e una paged MMU, per poi farsi una idea di cosa altro si possa fare (’case we want to reinvent the wheel) per limare al massimo il codice da scrivere senza scendere al compromesso dei task statici

ora, dagli studi e’ emerso che usare la MMU mc68851 e’ pari ad usare la MMU integrata in mc68030,40,60,..: stessa filosofia (paged MMU handling), stessa complessita’ (anzi la mc68851 e’ un filo + complessa, + transistor, qualche funzioncina in +, delle MMU integrate)

il punto allora e’:


 * il progetto e’ nato per scopo hobbistici
 * quindi ha poco man power e poco tempo a disposizione
 * il kernel vuole essere semplice
 * ma non cosi’ “castrato” da dover ripiegare sul multi-tastking statico
 * le cpu target sono tutte CPU mmu-less (tipo mc68HC000)
 * quindi serve supporto MMU hw, esterno, per realizzare “memoria virtuale a basso costo”
 * (che poi e’ il titolo di questo thread)
 * dove “costo” e’ espresso in termini di man power, si: proprio tempo e codice da scrivere (nonche’ bug, nella filosofia the more lines you write the more bugs you have to find)

una volta studiato cio’ che esiste, visti pregi e difetti, e relativi compromessi, si e’ pensato ad un possibile riutilizzo del nuovo know/how: quindi se prima ha avuto senso pensare (e studiare come) stare leggeri col codice impiegando una MMU sempliciotta come la mc68451, ora (anche, ma non solo, xke’ e’ un chip obsoleto, sprovvisto di doc) si pensa di riutilizzare quanto appreso in campo per confezionare qualcosa di nuovo che possa essere benissimo infilato in un progetto di sintesi di + ampio respiro

gia’, non e’ troppo complesso infatti recuperare il codice VHDL della “picoMMU” (che massimizza al massimo i compromessi circuitali ma anche e sopratutto di codice al lato OS) ed aggiungerla (proprio come blocco funzionale) al progetto di una cpu (e magari anche RISC) in sintesi: tutto OnChip, tutto semplice, tutto gestibile con poche risorse “umane”, senza dover scomodare soluzione “preconfezionate”, che sono, in tutta franchezza “grasso che cola”

chiudo lasciando intendere che il progetto della picoMMU e’ un filo + complesso di quanto ho riassunto prima come linee (o meglio bozza) base:

quanto ho implementato, infatti, modella lo spazio virtuale (VAddr) di un task in 4 blocchi distinti

1) stack 2) data 3) text (codice eseguibile) 4) shared memory

la traduzione VAddr –> PAddr passa dunque per 4 comparatori di area if (x in min..max) in_range=true if (!S) switch (Vaddr) // user space address ( range stack: PAddr=VAddr+stack.displacement; range data: PAddr=VAddr+data.displacement; range text: PAddr=VAddr+text.displacement; range shared: PAddr=VAddr+shared.displacement; default trap picoMMU_address_error; ) else PAddr=VAddr; // superuser space address

la picoMMU si compone di 4 registri che necessitano di aggiornamento ad ogni context switch

32bit stack.displacement; 32bit data.displacement; 32bit text.displacement; 32bit shared.displacement;

tot 4×32bit=4×4byte=16byte OverHead

(si, il 68000 ha 24bit di addr esterni, volendo si possono risparmiare 4byte spillando 1 byte per ogni registro: si hanno 12byte al posto di 16byte)

restano altri registri
 * da inizializzare al kernel_mmu_init
 * oppure per “task” particolari

32bit stack.range.min stack.range.max; 32bit data.range.min data.range.max; 32bit text.range.min text.range.max; 32bit shared.range.min shared.range.max;

un modello molto semplice ma efficace!

ma a livello di costi, per un hobbista, c’è comunque così tanta differenza fra una soluzione già bella e pronta (come la serie 683xx di Motorola/FreeScale) e una basata su 68HC000 + logica ad hoc?

assolutamente si!

in termini di codice da scrivere, in termini di riutilizzo di codice (specialmente vhdl), in termini di possibilita’ di impiego su altre cpu!

addr di 24 o 32bit ? eleganza e linearita’, salvo o non salvo il package, si chiese motorola

se la picoMMU e’ memorymapped in supervisior data area, allora aggiornare i suoi registri significa muovere 4 byte sul bus dati (ne + ne meno di una periferica qualsiasi, cosi’ e’ vista in supervisor data area). Ora, muovere sul package del 68000 gli addr bit son 24bit e sembra essere vantaggioso risparmiarsi 1 byte, ma si scopre invece che costa SEMPRE di meno una move.l di 4 byte che 3 move.b che 1 move.b, o da una move.w di 2 byte seguita da 1 move.b da 1byte. Costa di meno in termini di istruzioni e di cicli bus. Vero, non c’e’ nessun vantaggio =P

come nel caso della mc68451, anche questo approccio di traduzione da VA a PA per essere “stabile” costa (purtroppo) 4 stadi sincroni al clock della cpu. Costa dunque 4 cicli di clock, e bisogna tenerne conto.

4 cicli di clock e’ un limite imposto dalle tempistiche necessarie a propagare in modo corretto i segnali all’interno degli stadi, non tanto limiti ditenlogia a disposizione quanto limiti di progetto superabili SOLO riprogettando in modo + furbo

Nel mio caso occorre attendere un tempo necessario affinche’ gli indireizzi siano stabili, campionarli poi in un latch (campo VA). In questa fase vengono attivati i 4 comparatori dei range dei blocchi (stack,data,text,shared) bisognera’ attendere un tempo necessario affinche’ il risultato delle 4 comparazioni vada a selezionare il registo da dare in pasto alla ALU per il “giusto” displacement (stack.disp,data.disp,text.disp,shared.disp) a quel punto la alu avra’ 32bit stabili di address e 32bit stabili del displacemente e dovra’ sommare bit a bit per produrre in uscita finalmente il campo PA

il disegno + semplice che posso scrivere impiega 4 stadi, “garantiti ad informazione stabile”, pertanto chiede 4 colpi di clock

Potrei ridurre i colpi di clock prendnedo + confidenza con i veri tempi di propagaziione, trovando magari scorciatoie: e sara’ il prossimo passo, di raffinamento

forse potresti risparmiare un ciclo di clock eliminando il sommatore finale (e quindi anche la sua circuiteria), e sostituendolo con un selettore che preleva n bit alti dal VA, e i rimanenti m bit (bassi) dall’apposito displacement.

In pratica una volta che il VA diventa “stabile”, vengono costruiti 4 indirizzi fisici “al volo”, prelevando i suoi n bit alti, e gli m bit (bassi) dei 4 displacement. A questo punto il comparatore dovrà semplicemente scegliere fra quale di questi 4.

Quindi avresti una sorta di paginazione della memoria (soluzione meno generale / flessibile rispetto alla tua), che potrebbe anche andare bene.

Certo, bisogna vedere sempre in che modo si prevede di implementare il kernel e le applicazioni, ma potrebbe rivelarsi un buon compromesso.

il super trucco, volendo c’e'!

e’ l’asso nella manica poco elegante ma molto efficacie che vorresti non dover giocare se non proprio proprio non ci sono altre carte, xke’ costa, e costa parecchio (in termini di euro al chip)

si puo’ pensare di ricorrere ad PLL per raddoppiare la frequenza di clock interna alla CPLD/FPGA

dunque, il clock CPU e’ di 12.5Mhz, con un PLL posso raddoppiarlo 2X in locale per una logica programmabile che regge tranquillamente fino a 50Mhz (con tempi di propagazione delle celle garantiti essere inferiori a 1/50Mhz) anche nei modelli economici, e! cosa essenziale, e! con un corridoio di aggancio di soli 5nsec di ritardo, quindi di fatto posso comprimere 4 cicli di clock in 2 cicli di clock senza stravolgere il progetto della picoMMU restando perfettamente allineato con il clock della CPU

volevo ordinare un paio di PLL da Distrilect semi, un mc88920 ha un syncing addirittura + veloce di 5nec richiesti: aggancia in in 2.5nsec

poi ho scoperto che queste meravigliosi PLL sono gli stessi PLL montati sull’apple LC475: in Distrilect c’era una ottima fornitura, alcuni addirittura largamente superiori ai requisiti

–> MC88920 is rated at 50MHz (2×25MHz bus –> MC88916DW70 is rated at 70MHz (2×35MHz bus) –> MC88916DW80 is rated at 80MHz (2×40MHz bus)

il modello + semplice costa oltre 40 euro, su ebay ho trovato 2 macchine LC475 funzionanti ed intere a 30 euro + 10 di shipping.

L’hobbista si arrangia, anche dissaldando un chip SMD per risaldarlo su adattatore DIL (5 euro tutto compreso dalla Cina) =P

ROFL: mitico! :D

Comunque aumentando il clock dell’FPGA… stai barando!!! :D :D :D

Però non credo che si possano dimezzare i cicli di clock. Molto dipende dal tempo che impiega l’address bus per stabilizzarsi. E’ soltanto quando il suo valore si trova stabilmente nel latch dell’FPGA, che è possibile poi “lavorare” anche a frequenze maggiori.

eh si, giocarsi l’asso nella manica e’ barare =P

tuttavia e’ un baro efficente, cioe’ che garantisce il risultato, xke’ se esternamente alla CPLD/FPGA ci si sincronizza su valori stabili dell’Addr proprio sul /AS (address strobe) della CPI, di li in poi, una volta campionati bit e’ affare della logica programmabile, la quale internamente e’ capace di propagare informazioni fra celle in tempi inferiori a 1/5Mhz, per esempio

e dunque stringendo stringendo, se i tempi di propagazione di un agglomerato di celle (e qui dipende dai percorsi segnati dal compilatore VHDL to bitstream, ma solitamente sceglie percorsi subottimi “abbastanza” buoni sia per spazio che per tempo) reggono allora si puo’ fare l’asso nella manica ha proposto di fare: dimezzare i cicli di clock visti da tutto cio’ che segue la picoMMU

tra l’altro si possono costruire half-adder molto veloci e comodi: il punto xro’, va detto, il punto rimane il disegno a stadi strettamente sincroni, xke’ tecnicamente gia’ il disegno del 68000 rispetto al disegno del 6800 ci insegna che si possono benissimo rilassare i vincoli sincroni pur garantendo tempistiche e funzionamento: ho ancora poca malizia e poche conoscenze in campo di logiche di sintesi per poter definire meccanismi asincroni infra stadio (per ridurre gli stadi), tuttavia e’ quantomeno intuibile il poter fare altrettanto internamente alla CPLD/FPGA

ah, in caso di IRQ, la picoMMU si vede un FCR proveniente da text&data-superuser-space, quindi cortocircuita tutti gli stadi a seguire per forwardare in uscita direttamente quanto ha campionato in ingresso: PA=VA in 1 solo ciclo di clock!