sdram: properly support multiple ramdisks, so that ramdiskX corresponds to sdZX

This commit is contained in:
cinap_lenrek 2018-05-29 22:50:04 +02:00
parent f1eb657db0
commit 16c87febd3
2 changed files with 64 additions and 61 deletions

View file

@ -503,9 +503,10 @@ to use as a root device for bootstrapping.
.SS \fLramdisk\fIX\fL=\fIsize\fP .SS \fLramdisk\fIX\fL=\fIsize\fP
.SS \fLramdisk\fIX\fL=\fIsize sectorsize\fP .SS \fLramdisk\fIX\fL=\fIsize sectorsize\fP
.SS \fLramdisk\fIX\fL=\fIaddress size sectorsize\fP .SS \fLramdisk\fIX\fL=\fIaddress size sectorsize\fP
This reserves physical memory as a ramdisk that will appear as an This reserves physical memory as a ramdisk that will appear as
.IR sd(3) .IR sd(3)
device. When the device \fLsdZ\fIX\fR.
When the
.I address .I address
argument is omited or zero, then the ramdisk will be allocated argument is omited or zero, then the ramdisk will be allocated
from the top of physical memory. from the top of physical memory.

View file

@ -12,9 +12,8 @@
#include "../port/sd.h" #include "../port/sd.h"
typedef struct Ctlr Ctlr; typedef struct Ramdisk Ramdisk;
struct Ctlr { struct Ramdisk {
SDev *dev;
Segment *seg; Segment *seg;
Segio sio; Segio sio;
@ -27,7 +26,7 @@ struct Ctlr {
Physseg; Physseg;
}; };
static Ctlr ctlrs[4]; static Ramdisk rds[4];
extern SDifc sdramifc; extern SDifc sdramifc;
@ -74,7 +73,7 @@ ramdiskalloc(uvlong base, ulong pages)
} }
static void static void
ramdiskinit0(Ctlr *ctlr, uvlong base, uvlong size, ulong ss) ramdiskinit0(Ramdisk *rd, uvlong base, uvlong size, ulong ss)
{ {
ulong nb, off; ulong nb, off;
@ -90,22 +89,22 @@ ramdiskinit0(Ctlr *ctlr, uvlong base, uvlong size, ulong ss)
base &= ~(BY2PG-1); base &= ~(BY2PG-1);
if(size == 0 || size != (uintptr)size){ if(size == 0 || size != (uintptr)size){
print("%s: invalid parameters\n", ctlr->name); print("%s: invalid parameters\n", rd->name);
return; return;
} }
base = ramdiskalloc(base, size/BY2PG); base = ramdiskalloc(base, size/BY2PG);
if(base == 0){ if(base == 0){
print("%s: allocation failed\n", ctlr->name); print("%s: allocation failed\n", rd->name);
return; return;
} }
ctlr->nb = nb; rd->nb = nb;
ctlr->ss = ss; rd->ss = ss;
ctlr->off = off; rd->off = off;
ctlr->pa = base;
ctlr->size = size; rd->pa = base;
print("%s: %llux+%lud %llud %lud (%lud sectors)\n", rd->size = size;
ctlr->name, (uvlong)ctlr->pa, ctlr->off, (uvlong)ctlr->size, ctlr->ss, ctlr->nb); rd->attr = SG_CACHED;
} }
static vlong static vlong
@ -125,18 +124,18 @@ getsizenum(char **p)
void void
ramdiskinit(void) ramdiskinit(void)
{ {
Ctlr *ctlr; Ramdisk *rd;
uvlong a[3]; uvlong a[3];
char *p; char *p;
int ctlrno, n; int subno, n;
for(ctlrno=0; ctlrno<nelem(ctlrs); ctlrno++){ for(subno=0; subno<nelem(rds); subno++){
ctlr = &ctlrs[ctlrno]; rd = &rds[subno];
if(ctlr->nb != 0) if(rd->nb != 0)
continue; continue;
snprint(ctlr->name = ctlr->buf, sizeof(ctlr->buf), "ramdisk%d", ctlrno); snprint(rd->name = rd->buf, sizeof(rd->buf), "ramdisk%d", subno);
if((p = getconf(ctlr->name)) == nil) if((p = getconf(rd->name)) == nil)
continue; continue;
for(n = 0; n < nelem(a); n++){ for(n = 0; n < nelem(a); n++){
@ -153,13 +152,13 @@ ramdiskinit(void)
} }
switch(n){ switch(n){
case 1: /* ramdiskX=size */ case 1: /* ramdiskX=size */
ramdiskinit0(ctlr, 0, a[0], 0); ramdiskinit0(rd, 0, a[0], 0);
break; break;
case 2: /* ramdiskX=size ss */ case 2: /* ramdiskX=size ss */
ramdiskinit0(ctlr, 0, a[0], (ulong)a[1]); ramdiskinit0(rd, 0, a[0], (ulong)a[1]);
break; break;
case 3: /* ramdiskX=base size ss */ case 3: /* ramdiskX=base size ss */
ramdiskinit0(ctlr, a[0], a[1], (ulong)a[2]); ramdiskinit0(rd, a[0], a[1], (ulong)a[2]);
break; break;
} }
} }
@ -169,65 +168,69 @@ static SDev*
rampnp(void) rampnp(void)
{ {
SDev *sdev; SDev *sdev;
Ctlr *ctlr;
for(ctlr = ctlrs; ctlr < &ctlrs[nelem(ctlrs)]; ctlr++){ sdev = xalloc(sizeof(SDev));
if(ctlr->nb == 0 || ctlr->dev != nil) if(sdev == nil)
continue; return nil;
sdev = malloc(sizeof(SDev));
if(sdev == nil) sdev->idno = 'Z';
break; sdev->ifc = &sdramifc;
sdev->idno = 'Z'; sdev->nunit = nelem(rds);
sdev->ifc = &sdramifc;
sdev->nunit = 1; return sdev;
sdev->ctlr = ctlr;
ctlr->dev = sdev;
return sdev;
}
return nil;
} }
static int static int
ramenable(SDev* dev) ramverify(SDunit *unit)
{ {
Ctlr *ctlr = dev->ctlr; Ramdisk *rd = &rds[unit->subno];
ctlr->attr = SG_CACHED; if(rd->nb == 0)
ctlr->seg = newseg(SG_PHYSICAL, UTZERO, ctlr->size/BY2PG);
if(ctlr->seg == nil)
return 0; return 0;
ctlr->seg->pseg = ctlr;
return 1;
}
static int unit->inquiry[0] = 0;
ramverify(SDunit*) unit->inquiry[1] = 0;
{ unit->inquiry[4] = sizeof unit->inquiry - 4;
strcpy((char*)unit->inquiry+8, rd->name);
return 1; return 1;
} }
static int static int
ramonline(SDunit *unit) ramonline(SDunit *unit)
{ {
Ctlr *ctlr = unit->dev->ctlr; Ramdisk *rd = &rds[unit->subno];
unit->sectors = ctlr->nb;
unit->secsize = ctlr->ss; if(unit->sectors != 0)
return 1; return 1;
rd->seg = newseg(SG_PHYSICAL, UTZERO, rd->size/BY2PG);
if(rd->seg == nil)
return 0;
rd->seg->pseg = rd;
unit->sectors = rd->nb;
unit->secsize = rd->ss;
return 2;
} }
static int static int
ramrctl(SDunit *unit, char *p, int l) ramrctl(SDunit *unit, char *p, int l)
{ {
return snprint(p, l, "geometry %llud %ld\n", Ramdisk *rd = &rds[unit->subno];
unit->sectors, unit->secsize);
return snprint(p, l, "geometry %llud %ld\nalignment %lud %lud\n",
unit->sectors, unit->secsize,
(ulong)BY2PG, rd->off / unit->secsize);
} }
static long static long
rambio(SDunit *unit, int, int write, void *data, long nb, uvlong bno) rambio(SDunit *unit, int, int write, void *data, long nb, uvlong bno)
{ {
Ctlr *ctlr = unit->dev->ctlr; Ramdisk *rd = &rds[unit->subno];
long secsize = unit->secsize; long secsize = unit->secsize;
return segio(&ctlr->sio, ctlr->seg, data, nb*secsize, bno*secsize + ctlr->off, !write);
return segio(&rd->sio, rd->seg, data, nb*secsize, bno*secsize + rd->off, !write);
} }
static int static int
@ -247,7 +250,6 @@ ramrio(SDreq *r)
SDifc sdramifc = { SDifc sdramifc = {
.name = "ram", .name = "ram",
.pnp = rampnp, .pnp = rampnp,
.enable = ramenable,
.verify = ramverify, .verify = ramverify,
.online = ramonline, .online = ramonline,
.rctl = ramrctl, .rctl = ramrctl,