sb16: new approach, works in qemu
This commit is contained in:
parent
e7e04b5cbb
commit
b74418c2ce
File diff suppressed because it is too large
Load diff
|
@ -857,7 +857,7 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
|
||||||
dmaend(DMAchan);
|
dmaend(DMAchan);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread);
|
dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread ? DMAREAD : DMAWRITE);
|
||||||
if(dp->len < 0)
|
if(dp->len < 0)
|
||||||
error(Eio);
|
error(Eio);
|
||||||
|
|
||||||
|
@ -999,7 +999,7 @@ floppyformat(FDrive *dp, Cmdbuf *cb)
|
||||||
dmaend(DMAchan);
|
dmaend(DMAchan);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
if(dmasetup(DMAchan, buf, bp-buf, 0) < 0)
|
if(dmasetup(DMAchan, buf, bp-buf, DMAWRITE) < 0)
|
||||||
error(Eio);
|
error(Eio);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct DMAxfer
|
||||||
int blen; /* bounce buffer length */
|
int blen; /* bounce buffer length */
|
||||||
void* va; /* virtual address destination/src */
|
void* va; /* virtual address destination/src */
|
||||||
long len; /* bytes to be transferred */
|
long len; /* bytes to be transferred */
|
||||||
int isread;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,7 +81,7 @@ _i8237alloc(void)
|
||||||
if(i8237dma > 2)
|
if(i8237dma > 2)
|
||||||
i8237dma = 2;
|
i8237dma = 2;
|
||||||
|
|
||||||
bva = xspanalloc(64*1024*i8237dma, BY2PG, 64*1024);
|
bva = xspanalloc(64*1024*i8237dma, 0, 64*1024);
|
||||||
if(bva == nil || PADDR(bva)+64*1024*i8237dma > 16*MB){
|
if(bva == nil || PADDR(bva)+64*1024*i8237dma > 16*MB){
|
||||||
/*
|
/*
|
||||||
* This will panic with the current
|
* This will panic with the current
|
||||||
|
@ -137,11 +137,38 @@ dmainit(int chan, int maxtransfer)
|
||||||
xp->bpa = PADDR(xp->bva);
|
xp->bpa = PADDR(xp->bva);
|
||||||
xp->blen = maxtransfer;
|
xp->blen = maxtransfer;
|
||||||
xp->len = 0;
|
xp->len = 0;
|
||||||
xp->isread = 0;
|
xp->flags = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
dmabva(int chan)
|
||||||
|
{
|
||||||
|
DMA *dp;
|
||||||
|
DMAxfer *xp;
|
||||||
|
|
||||||
|
dp = &dma[(chan>>2)&1];
|
||||||
|
chan = chan & 3;
|
||||||
|
xp = &dp->x[chan];
|
||||||
|
return xp->bva;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dmacount(int chan)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
DMA *dp;
|
||||||
|
|
||||||
|
dp = &dma[(chan>>2)&1];
|
||||||
|
chan = chan & 3;
|
||||||
|
ilock(dp);
|
||||||
|
retval = inb(dp->count[chan]);
|
||||||
|
retval |= inb(dp->count[chan]) << 8;
|
||||||
|
iunlock(dp);
|
||||||
|
return ((retval<<dp->shift)+1) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setup a dma transfer. if the destination is not in kernel
|
* setup a dma transfer. if the destination is not in kernel
|
||||||
* memory, allocate a page for the transfer.
|
* memory, allocate a page for the transfer.
|
||||||
|
@ -153,7 +180,7 @@ dmainit(int chan, int maxtransfer)
|
||||||
* boundaries)
|
* boundaries)
|
||||||
*/
|
*/
|
||||||
long
|
long
|
||||||
dmasetup(int chan, void *va, long len, int isread)
|
dmasetup(int chan, void *va, long len, int flags)
|
||||||
{
|
{
|
||||||
DMA *dp;
|
DMA *dp;
|
||||||
ulong pa;
|
ulong pa;
|
||||||
|
@ -175,11 +202,11 @@ dmasetup(int chan, void *va, long len, int isread)
|
||||||
return -1;
|
return -1;
|
||||||
if(len > xp->blen)
|
if(len > xp->blen)
|
||||||
len = xp->blen;
|
len = xp->blen;
|
||||||
if(!isread)
|
if(!(flags & DMAREAD))
|
||||||
memmove(xp->bva, va, len);
|
memmove(xp->bva, va, len);
|
||||||
xp->va = va;
|
xp->va = va;
|
||||||
xp->len = len;
|
xp->len = len;
|
||||||
xp->isread = isread;
|
xp->flags = flags;
|
||||||
pa = xp->bpa;
|
pa = xp->bpa;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -189,7 +216,7 @@ dmasetup(int chan, void *va, long len, int isread)
|
||||||
* this setup must be atomic
|
* this setup must be atomic
|
||||||
*/
|
*/
|
||||||
ilock(dp);
|
ilock(dp);
|
||||||
mode = (isread ? 0x44 : 0x48) | chan;
|
mode = ((flags & DMAREAD) ? 0x44 : 0x48) | ((flags & DMALOOP) ? 0x10 : 0) | chan;
|
||||||
outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
|
outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
|
||||||
outb(dp->page[chan], pa>>16);
|
outb(dp->page[chan], pa>>16);
|
||||||
outb(dp->cbp, 0); /* set count & address to their first byte */
|
outb(dp->cbp, 0); /* set count & address to their first byte */
|
||||||
|
@ -238,7 +265,7 @@ dmaend(int chan)
|
||||||
iunlock(dp);
|
iunlock(dp);
|
||||||
|
|
||||||
xp = &dp->x[chan];
|
xp = &dp->x[chan];
|
||||||
if(xp->len == 0 || !xp->isread)
|
if(xp->len == 0 || !(xp->flags & DMAREAD))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -248,17 +275,3 @@ dmaend(int chan)
|
||||||
xp->len = 0;
|
xp->len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
int
|
|
||||||
dmacount(int chan)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
DMA *dp;
|
|
||||||
|
|
||||||
dp = &dma[(chan>>2)&1];
|
|
||||||
outb(dp->cbp, 0);
|
|
||||||
retval = inb(dp->count[chan]);
|
|
||||||
retval |= inb(dp->count[chan]) << 8;
|
|
||||||
return((retval<<dp->shift)+1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -18,10 +18,14 @@ int cpuidentify(void);
|
||||||
void cpuidprint(void);
|
void cpuidprint(void);
|
||||||
void (*cycles)(uvlong*);
|
void (*cycles)(uvlong*);
|
||||||
void delay(int);
|
void delay(int);
|
||||||
|
void* dmabva(int);
|
||||||
int dmacount(int);
|
int dmacount(int);
|
||||||
int dmadone(int);
|
int dmadone(int);
|
||||||
void dmaend(int);
|
void dmaend(int);
|
||||||
int dmainit(int, int);
|
int dmainit(int, int);
|
||||||
|
#define DMAWRITE 0
|
||||||
|
#define DMAREAD 1
|
||||||
|
#define DMALOOP 2
|
||||||
long dmasetup(int, void*, long, int);
|
long dmasetup(int, void*, long, int);
|
||||||
#define evenaddr(x) /* x86 doesn't care */
|
#define evenaddr(x) /* x86 doesn't care */
|
||||||
void fpclear(void);
|
void fpclear(void);
|
||||||
|
@ -181,5 +185,3 @@ int xchgw(ushort*, int);
|
||||||
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
|
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
|
||||||
#define KADDR(a) kaddr(a)
|
#define KADDR(a) kaddr(a)
|
||||||
#define PADDR(a) paddr((void*)(a))
|
#define PADDR(a) paddr((void*)(a))
|
||||||
|
|
||||||
#define dcflush(a, b)
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ enum {
|
||||||
Qaudioctl,
|
Qaudioctl,
|
||||||
Qaudiostatus,
|
Qaudiostatus,
|
||||||
Qvolume,
|
Qvolume,
|
||||||
|
|
||||||
Maxaudioprobes = 8,
|
Maxaudioprobes = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,19 +49,26 @@ audioreset(void)
|
||||||
int i, ctlrno = 0;
|
int i, ctlrno = 0;
|
||||||
Audio **pp;
|
Audio **pp;
|
||||||
Audioprobe *probe;
|
Audioprobe *probe;
|
||||||
|
|
||||||
pp = &audiodevs;
|
pp = &audiodevs;
|
||||||
*pp = malloc(sizeof(Audio));
|
*pp = malloc(sizeof(Audio));
|
||||||
(*pp)->ctlrno = ctlrno++;
|
|
||||||
for(i = 0; i < naudioprobes; i++){
|
for(i=0; i<naudioprobes; i++){
|
||||||
probe = &audioprobes[i];
|
probe = &audioprobes[i];
|
||||||
(*pp)->name = probe->name;
|
|
||||||
while(!probe->probe(*pp)){
|
for(;;){
|
||||||
|
memset(*pp, 0, sizeof(Audio));
|
||||||
|
(*pp)->ctlrno = ctlrno;
|
||||||
|
(*pp)->name = probe->name;
|
||||||
|
if(probe->probe(*pp))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ctlrno++;
|
||||||
pp = &(*pp)->next;
|
pp = &(*pp)->next;
|
||||||
*pp = malloc(sizeof(Audio));
|
*pp = malloc(sizeof(Audio));
|
||||||
(*pp)->ctlrno = ctlrno++;
|
|
||||||
(*pp)->name = probe->name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(*pp);
|
free(*pp);
|
||||||
*pp = nil;
|
*pp = nil;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue