summaryrefslogtreecommitdiff
path: root/os/mpc/cpm.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/mpc/cpm.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/mpc/cpm.c')
-rw-r--r--os/mpc/cpm.c695
1 files changed, 0 insertions, 695 deletions
diff --git a/os/mpc/cpm.c b/os/mpc/cpm.c
deleted file mode 100644
index e985d947..00000000
--- a/os/mpc/cpm.c
+++ /dev/null
@@ -1,695 +0,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-
-typedef struct Chanuse Chanuse;
-struct Chanuse {
- Lock;
- void* owner;
-} ;
-
-enum {
- BDSIZE= 1024, /* IO memory reserved for buffer descriptors */
- CPMSIZE= 1024, /* IO memory reserved for other uses */
-
- /* channel IDs */
- SCC1ID= 0,
- I2CID= 1,
- IDMA1ID= 1,
- SCC2ID= 4,
- SPIID= 5,
- IDMA2ID= 5,
- TIMERID= 5,
- SCC3ID= 8,
- SMC1ID= 9,
- DSP1ID= 9,
- SCC4ID= 12,
- SMC2ID= 13,
- DSP2ID= 13,
- NCPMID= 16,
-
- NSCC = 4,
-
- /* SCC.gsmr_l */
- ENR = 1<<5, /* enable receiver */
- ENT = 1<<4, /* enable transmitter */
-
- NSMC = 2,
-
- /* SMC.smcmr */
- TEN = 1<<1, /* transmitter enable */
- REN = 1<<0, /* receiver enable */
-};
-
-static Map bdmapv[BDSIZE/sizeof(BD)];
-static RMap bdmap = {"buffer descriptors"};
-
-static Map cpmmapv[CPMSIZE/sizeof(ulong)];
-static RMap cpmmap = {"CPM memory"};
-
-static Lock cpmlock;
-
-static struct {
- Lock;
- ulong avail;
-} brgens;
-
-static Chanuse cpmids[NCPMID];
-static CPMdev cpmdevinfo[] = {
- [CPscc1] {SCC1ID, 0x1E, 0xA00, 0x3C00},
- [CPscc2] {SCC2ID, 0x1D, 0xA20, 0x3D00},
- [CPscc3] {SCC3ID, 0x1C, 0xA40, 0x3E00},
- [CPscc4] {SCC4ID, 0x1B, 0xA60, 0x3F00},
- [CPsmc1] {SMC1ID, 0x04, 0xA80, 0x3E80},
- [CPsmc2] {SMC2ID, 0x03, 0xA90, 0x3F80},
- [CPdsp1] {DSP1ID, 0x16, 0, 0x3EC0},
- [CPdsp2] {DSP2ID, 0x16, 0, 0x3FC0},
- [CPidma1] {IDMA1ID, 0x15, 0, 0x3CC0},
- [CPidma2] {IDMA2ID, 0x14, 0, 0x3DC0},
- [CPtimer] {TIMERID, 0x11, 0, 0x3DB0},
- [CPspi] {SPIID, 0x05, 0xAA0, 0x3D80}, /* parameters relocated below */
- [CPi2c] {I2CID, 0x10, 0x860, 0x3C80}, /* parameters relocated below */
-};
-
-static void i2cspireloc(void);
-static void* relocateparam(ulong, int);
-
-/*
- * initialise the communications processor module
- * and associated device registers
- */
-void
-cpminit(void)
-{
- IMM *io;
-
- io = m->iomem;
- io->sdcr = 1;
- io->rccr = 0;
- io->rmds = 0;
- io->lccr = 0; /* disable LCD */
- io->vccr = 0; /* disable video */
- io->i2mod = 0; /* stop I2C */
- io->pcint = 0; /* disable all port C interrupts */
- io->pcso = 0;
- io->pcdir =0;
- io->pcpar = 0;
- io->pcdat = 0;
- io->papar = 0;
- io->padir = 0;
- io->paodr = 0;
- io->padat = 0;
- io->pbpar = 0;
- io->pbdir = 0;
- io->pbodr = 0;
- io->pbdat = 0;
- io->tgcr = 0x2222; /* reset timers, low-power stop */
- eieio();
-
- for(io->cpcr = 0x8001; io->cpcr & 1;) /* reset all CPM channels */
- eieio();
-
- mapinit(&bdmap, bdmapv, sizeof(bdmapv));
- mapfree(&bdmap, DPBASE, BDSIZE);
- mapinit(&cpmmap, cpmmapv, sizeof(cpmmapv));
- mapfree(&cpmmap, DPBASE+BDSIZE, CPMSIZE);
-
- if(m->cputype == 0x50 && (getimmr() & 0xFFFF) <= 0x2001)
- brgens.avail = 0x3;
- else
- brgens.avail = 0xF;
- i2cspireloc();
-}
-
-/*
- * return parameters defining a CPM device, given logical ID
- */
-CPMdev*
-cpmdev(int n)
-{
- CPMdev *d;
-
- if(n < 0 || n >= nelem(cpmdevinfo))
- panic("cpmdev");
- d = &cpmdevinfo[n];
- if(d->param == nil && d->pbase != 0){
- if((n == CPi2c || n == CPspi)){
- d->param = relocateparam(d->pbase, 0xB0-0x80); /* relocate */
- if(d->param == nil)
- return nil;
- } else
- d->param = (char*)m->iomem+d->pbase;
- }
- if(d->rbase != 0)
- d->regs = (char*)m->iomem+d->rbase;
- return d;
-}
-
-/*
- * issue a request to a CPM device
- */
-void
-cpmop(CPMdev *cpd, int op, int param)
-{
- IMM *io;
-
- ilock(&cpmlock);
- io = m->iomem;
- while(io->cpcr & 1)
- eieio();
- io->cpcr = (op<<8)|(cpd->id<<4)|(param<<1)|1;
- eieio();
- while(io->cpcr & 1)
- eieio();
- iunlock(&cpmlock);
-}
-
-/*
- * lock the shared IO memory and return a reference to it
- */
-IMM*
-ioplock(void)
-{
- ilock(&cpmlock);
- return m->iomem;
-}
-
-/*
- * release the lock on the shared IO memory
- */
-void
-iopunlock(void)
-{
- eieio();
- iunlock(&cpmlock);
-}
-
-/*
- * connect SCCx clocks in NSMI mode (x=1 for USB)
- */
-void
-sccnmsi(int x, int rcs, int tcs)
-{
- IMM *io;
- ulong v;
- int sh;
-
- sh = (x-1)*8; /* each SCCx field in sicr is 8 bits */
- v = (((rcs&7)<<3) | (tcs&7)) << sh;
- io = ioplock();
- io->sicr = (io->sicr & ~(0xFF<<sh)) | v;
- iopunlock();
-}
-
-/*
- * connect SMCx clock in NSMI mode
- */
-void
-smcnmsi(int x, int cs)
-{
- IMM *io;
- ulong v;
- int sh;
-
- if(x == 1)
- sh = 0;
- else
- sh = 16;
- v = cs << (12+sh);
- io = ioplock();
- io->simode = (io->simode & ~(0xF000<<sh)) | v; /* SMCx to NMSI mode, set Tx/Rx clock */
- iopunlock();
-}
-
-/*
- * claim the use of a CPM ID (SCC, SMC) that might be used by two mutually exclusive devices,
- * for the caller determined by the given parameter (which must be unique).
- * returns non-zero if the resource is already in use.
- */
-int
-cpmidopen(int id, void *owner)
-{
- Chanuse *use;
-
- use = &cpmids[id];
- ilock(use);
- if(use->owner != nil && use->owner != owner){
- iunlock(use);
- return -1;
- }
- use->owner = owner;
- iunlock(use);
- return 0;
-}
-
-/*
- * release a previously claimed CPM ID
- */
-void
-cpmidclose(int id)
-{
- Chanuse *use;
-
- use = &cpmids[id];
- ilock(use);
- use->owner = nil;
- iunlock(use);
-}
-
-/*
- * if SCC d is currently enabled, shut it down
- */
-void
-sccxstop(CPMdev *d)
-{
- SCC *scc;
-
- if(d == nil)
- return;
- scc = d->regs;
- if(scc->gsmrl & (ENT|ENR)){
- if(scc->gsmrl & ENT)
- cpmop(d, GracefulStopTx, 0);
- if(scc->gsmrl & ENR)
- cpmop(d, CloseRxBD, 0);
- delay(1);
- scc->gsmrl &= ~(ENT|ENR); /* disable current use */
- eieio();
- }
- scc->sccm = 0; /* mask interrupts */
-}
-
-/*
- * if SMC d is currently enabled, shut it down
- */
-void
-smcxstop(CPMdev *d)
-{
- SMC *smc;
-
- if(d == nil)
- return;
- smc = d->regs;
- if(smc->smcmr & (TEN|REN)){
- if(smc->smcmr & TEN)
- cpmop(d, StopTx, 0);
- if(smc->smcmr & REN)
- cpmop(d, CloseRxBD, 0);
- delay(1);
- smc->smcmr &= ~(TEN|REN);
- eieio();
- }
- smc->smcm = 0; /* mask interrupts */
-}
-
-/*
- * allocate a buffer descriptor
- */
-BD *
-bdalloc(int n)
-{
- ulong a;
-
- a = rmapalloc(&bdmap, 0, n*sizeof(BD), sizeof(BD));
- if(a == 0)
- panic("bdalloc");
- return KADDR(a);
-}
-
-/*
- * free a buffer descriptor
- */
-void
-bdfree(BD *b, int n)
-{
- if(b){
- eieio();
- mapfree(&bdmap, PADDR(b), n*sizeof(BD));
- }
-}
-
-/*
- * print a buffer descriptor and its data (when debugging)
- */
-void
-dumpbd(char *name, BD *b, int maxn)
-{
- uchar *d;
- int i;
-
- print("%s #%4.4lux: s=#%4.4ux l=%ud a=#%8.8lux", name, PADDR(b)&0xFFFF, b->status, b->length, b->addr);
- if(maxn > b->length)
- maxn = b->length;
- if(b->addr != 0){
- d = KADDR(b->addr);
- for(i=0; i<maxn; i++)
- print(" %2.2ux", d[i]);
- if(i < b->length)
- print(" ...");
- }
- print("\n");
-}
-
-/*
- * allocate memory from the shared IO memory space
- */
-void *
-cpmalloc(int n, int align)
-{
- ulong a;
-
- a = rmapalloc(&cpmmap, 0, n, align);
- if(a == 0)
- panic("cpmalloc");
- return KADDR(a);
-}
-
-/*
- * free previously allocated shared memory
- */
-void
-cpmfree(void *p, int n)
-{
- if(p != nil && n > 0){
- eieio();
- mapfree(&cpmmap, PADDR(p), n);
- }
-}
-
-/*
- * allocate a baud rate generator, returning its index
- * (or -1 if none is available)
- */
-int
-brgalloc(void)
-{
- int n;
-
- lock(&brgens);
- for(n=0; brgens.avail!=0; n++)
- if(brgens.avail & (1<<n)){
- brgens.avail &= ~(1<<n);
- unlock(&brgens);
- return n;
- }
- unlock(&brgens);
- return -1;
-}
-
-/*
- * free a previously allocated baud rate generator
- */
-void
-brgfree(int n)
-{
- if(n >= 0){
- if(n > 3 || brgens.avail & (1<<n))
- panic("brgfree");
- lock(&brgens);
- brgens.avail |= 1 << n;
- unlock(&brgens);
- }
-}
-
-/*
- * return a value suitable for loading into a baud rate
- * generator to produce the given rate if the generator
- * is prescaled by the given amount (typically 16).
- * the value must be or'd with BaudEnable to start the generator.
- */
-ulong
-baudgen(int rate, int scale)
-{
- int d;
-
- rate *= scale;
- d = (2*m->cpuhz+rate)/(2*rate) - 1;
- if(d < 0)
- d = 0;
- if(d >= (1<<12))
- return ((d+15)>>(4-1))|1; /* divider too big: enable prescale by 16 */
- return d<<1;
-}
-
-/*
- * initialise receive and transmit buffer rings.
- */
-int
-ioringinit(Ring* r, int nrdre, int ntdre, int bufsize)
-{
- int i, x;
-
- /* the ring entries must be aligned on sizeof(BD) boundaries */
- r->nrdre = nrdre;
- if(r->rdr == nil)
- r->rdr = bdalloc(nrdre);
- /* the buffer size must align with cache lines since the cache doesn't snoop */
- bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1);
- if(r->rrb == nil)
- r->rrb = malloc(nrdre*bufsize);
- if(r->rdr == nil || r->rrb == nil)
- return -1;
- dcflush(r->rrb, nrdre*bufsize);
- x = PADDR(r->rrb);
- for(i = 0; i < nrdre; i++){
- r->rdr[i].length = 0;
- r->rdr[i].addr = x;
- r->rdr[i].status = BDEmpty|BDInt;
- x += bufsize;
- }
- r->rdr[i-1].status |= BDWrap;
- r->rdrx = 0;
-
- r->ntdre = ntdre;
- if(r->tdr == nil)
- r->tdr = bdalloc(ntdre);
- if(r->txb == nil)
- r->txb = malloc(ntdre*sizeof(Block*));
- if(r->tdr == nil || r->txb == nil)
- return -1;
- for(i = 0; i < ntdre; i++){
- r->txb[i] = nil;
- r->tdr[i].addr = 0;
- r->tdr[i].length = 0;
- r->tdr[i].status = 0;
- }
- r->tdr[i-1].status |= BDWrap;
- r->tdrh = 0;
- r->tdri = 0;
- r->ntq = 0;
- return 0;
-}
-
-/*
- * Allocate a new parameter block for I2C or SPI,
- * and plant a pointer to it for the microcode, returning the kernel address.
- * See Motorola errata and microcode package:
- * the design botch is that the parameters for the SCC2 ethernet overlap the
- * SPI/I2C parameter space; this compensates by relocating the latter.
- * This routine may be used iff i2cspireloc is used (and it is, above).
- */
-static void*
-relocateparam(ulong olda, int nb)
-{
- void *p;
-
- if(olda < (ulong)m->iomem)
- olda += (ulong)m->iomem;
- p = cpmalloc(nb, 32); /* ``RPBASE must be multiple of 32'' */
- if(p == nil)
- return p;
- *(ushort*)KADDR(olda+0x2C) = PADDR(p); /* set RPBASE */
- eieio();
- return p;
-}
-
-/*
- * I2C/SPI microcode package from Motorola
- * (to relocate I2C/SPI parameters), which was distributed
- * on their web site in S-record format.
- *
- * May 1998
- */
-
-/*S00600004844521B*/
-static ulong ubase1 = 0x2000;
-static ulong ucode1[] = {
- /* #02202000 */ 0x7FFFEFD9,
- /* #02202004 */ 0x3FFD0000,
- /* #02202008 */ 0x7FFB49F7,
- /* #0220200C */ 0x7FF90000,
- /* #02202010 */ 0x5FEFADF7,
- /* #02202014 */ 0x5F89ADF7,
- /* #02202018 */ 0x5FEFAFF7,
- /* #0220201C */ 0x5F89AFF7,
- /* #02202020 */ 0x3A9CFBC8,
- /* #02202024 */ 0xE7C0EDF0,
- /* #02202028 */ 0x77C1E1BB,
- /* #0220202C */ 0xF4DC7F1D,
- /* #02202030 */ 0xABAD932F,
- /* #02202034 */ 0x4E08FDCF,
- /* #02202038 */ 0x6E0FAFF8,
- /* #0220203C */ 0x7CCF76CF,
- /* #02202040 */ 0xFD1FF9CF,
- /* #02202044 */ 0xABF88DC6,
- /* #02202048 */ 0xAB5679F7,
- /* #0220204C */ 0xB0937383,
- /* #02202050 */ 0xDFCE79F7,
- /* #02202054 */ 0xB091E6BB,
- /* #02202058 */ 0xE5BBE74F,
- /* #0220205C */ 0xB3FA6F0F,
- /* #02202060 */ 0x6FFB76CE,
- /* #02202064 */ 0xEE0DF9CF,
- /* #02202068 */ 0x2BFBEFEF,
- /* #0220206C */ 0xCFEEF9CF,
- /* #02202070 */ 0x76CEAD24,
- /* #02202074 */ 0x90B2DF9A,
- /* #02202078 */ 0x7FDDD0BF,
- /* #0220207C */ 0x4BF847FD,
- /* #02202080 */ 0x7CCF76CE,
- /* #02202084 */ 0xCFEF7E1F,
- /* #02202088 */ 0x7F1D7DFD,
- /* #0220208C */ 0xF0B6EF71,
- /* #02202090 */ 0x7FC177C1,
- /* #02202094 */ 0xFBC86079,
- /* #02202098 */ 0xE722FBC8,
- /* #0220209C */ 0x5FFFDFFF,
- /* #022020A0 */ 0x5FB2FFFB,
- /* #022020A4 */ 0xFBC8F3C8,
- /* #022020A8 */ 0x94A67F01,
- /* #022020AC */ 0x7F1D5F39,
- /* #022020B0 */ 0xAFE85F5E,
- /* #022020B4 */ 0xFFDFDF96,
- /* #022020B8 */ 0xCB9FAF7D,
- /* #022020BC */ 0x5FC1AFED,
- /* #022020C0 */ 0x8C1C5FC1,
- /* #022020C4 */ 0xAFDD5FC3,
- /* #022020C8 */ 0xDF9A7EFD,
- /* #022020CC */ 0xB0B25FB2,
- /* #022020D0 */ 0xFFFEABAD,
- /* #022020D4 */ 0x5FB2FFFE,
- /* #022020D8 */ 0x5FCE600B,
- /* #022020DC */ 0xE6BB600B,
- /* #022020E0 */ 0x5FCEDFC6,
- /* #022020E4 */ 0x27FBEFDF,
- /* #022020E8 */ 0x5FC8CFDE,
- /* #022020EC */ 0x3A9CE7C0,
- /* #022020F0 */ 0xEDF0F3C8,
- /* #022020F4 */ 0x7F0154CD,
- /* #022020F8 */ 0x7F1D2D3D,
- /* #022020FC */ 0x363A7570,
- /* #02202100 */ 0x7E0AF1CE,
- /* #02202104 */ 0x37EF2E68,
- /* #02202108 */ 0x7FEE10EC,
- /* #0220210C */ 0xADF8EFDE,
- /* #02202110 */ 0xCFEAE52F,
- /* #02202114 */ 0x7D0FE12B,
- /* #02202118 */ 0xF1CE5F65,
- /* #0220211C */ 0x7E0A4DF8,
- /* #02202120 */ 0xCFEA5F72,
- /* #02202124 */ 0x7D0BEFEE,
- /* #02202128 */ 0xCFEA5F74,
- /* #0220212C */ 0xE522EFDE,
- /* #02202130 */ 0x5F74CFDA,
- /* #02202134 */ 0x0B627385,
- /* #02202138 */ 0xDF627E0A,
- /* #0220213C */ 0x30D8145B,
- /* #02202140 */ 0xBFFFF3C8,
- /* #02202144 */ 0x5FFFDFFF,
- /* #02202148 */ 0xA7F85F5E,
- /* #0220214C */ 0xBFFE7F7D,
- /* #02202150 */ 0x10D31450,
- /* #02202154 */ 0x5F36BFFF,
- /* #02202158 */ 0xAF785F5E,
- /* #0220215C */ 0xBFFDA7F8,
- /* #02202160 */ 0x5F36BFFE,
- /* #02202164 */ 0x77FD30C0,
- /* #02202168 */ 0x4E08FDCF,
- /* #0220216C */ 0xE5FF6E0F,
- /* #02202170 */ 0xAFF87E1F,
- /* #02202174 */ 0x7E0FFD1F,
- /* #02202178 */ 0xF1CF5F1B,
- /* #0220217C */ 0xABF80D5E,
- /* #02202180 */ 0x5F5EFFEF,
- /* #02202184 */ 0x79F730A2,
- /* #02202188 */ 0xAFDD5F34,
- /* #0220218C */ 0x47F85F34,
- /* #02202190 */ 0xAFED7FDD,
- /* #02202194 */ 0x50B24978,
- /* #02202198 */ 0x47FD7F1D,
- /* #0220219C */ 0x7DFD70AD,
- /* #022021A0 */ 0xEF717EC1,
- /* #022021A4 */ 0x6BA47F01,
- /* #022021A8 */ 0x2D267EFD,
- /* #022021AC */ 0x30DE5F5E,
- /* #022021B0 */ 0xFFFD5F5E,
- /* #022021B4 */ 0xFFEF5F5E,
- /* #022021B8 */ 0xFFDF0CA0,
- /* #022021BC */ 0xAFED0A9E,
- /* #022021C0 */ 0xAFDD0C3A,
- /* #022021C4 */ 0x5F3AAFBD,
- /* #022021C8 */ 0x7FBDB082,
- /* #022021CC */ 0x5F8247F8,
-};
-
-/*S00600004844521B*/
-static ulong ubase2 = 0x2F00;
-static ulong ucode2[] = {
- /* #02202F00 */ 0x3E303430,
- /* #02202F04 */ 0x34343737,
- /* #02202F08 */ 0xABF7BF9B,
- /* #02202F0C */ 0x994B4FBD,
- /* #02202F10 */ 0xBD599493,
- /* #02202F14 */ 0x349FFF37,
- /* #02202F18 */ 0xFB9B177D,
- /* #02202F1C */ 0xD9936956,
- /* #02202F20 */ 0xBBFDD697,
- /* #02202F24 */ 0xBDD2FD11,
- /* #02202F28 */ 0x31DB9BB3,
- /* #02202F2C */ 0x63139637,
- /* #02202F30 */ 0x93733693,
- /* #02202F34 */ 0x193137F7,
- /* #02202F38 */ 0x331737AF,
- /* #02202F3C */ 0x7BB9B999,
- /* #02202F40 */ 0xBB197957,
- /* #02202F44 */ 0x7FDFD3D5,
- /* #02202F48 */ 0x73B773F7,
- /* #02202F4C */ 0x37933B99,
- /* #02202F50 */ 0x1D115316,
- /* #02202F54 */ 0x99315315,
- /* #02202F58 */ 0x31694BF4,
- /* #02202F5C */ 0xFBDBD359,
- /* #02202F60 */ 0x31497353,
- /* #02202F64 */ 0x76956D69,
- /* #02202F68 */ 0x7B9D9693,
- /* #02202F6C */ 0x13131979,
- /* #02202F70 */ 0x79376935,
-};
-
-/*
- * compensate for chip design botch by installing
- * microcode to relocate I2C and SPI parameters away
- * from the ethernet parameters
- */
-static void
-i2cspireloc(void)
-{
- IMM *io;
- static int done;
-
- if(done)
- return;
- io = m->iomem;
- io->rccr &= ~3;
- memmove((uchar*)m->iomem+ubase1, ucode1, sizeof(ucode1));
- memmove((uchar*)m->iomem+ubase2, ucode2, sizeof(ucode2));
- io->rctr1 = 0x802a; /* relocate SPI */
- io->rctr2 = 0x8028; /* relocate SPI */
- io->rctr3 = 0x802e; /* relocate I2C */
- io->rctr4 = 0x802c; /* relocate I2C */
- io->rccr |= 1;
- done = 1;
-}