sdram: properly support multiple ramdisks, so that ramdiskX corresponds to sdZX
This commit is contained in:
parent
f1eb657db0
commit
16c87febd3
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue