fix ide, pit interfaces
This commit is contained in:
parent
6c8acf9e04
commit
19297caf0d
|
@ -42,5 +42,5 @@ pit8253_timerinit(void)
|
||||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
|
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
|
||||||
outb(IO_TIMER1, TIMER_DIV(100) % 256);
|
outb(IO_TIMER1, TIMER_DIV(100) % 256);
|
||||||
outb(IO_TIMER1, TIMER_DIV(100) / 256);
|
outb(IO_TIMER1, TIMER_DIV(100) / 256);
|
||||||
irq_setmask_8259A(irq_mask_8259A & ~(1<<IRQ_TIMER));
|
irq_enable(IRQ_TIMER);
|
||||||
}
|
}
|
||||||
|
|
19
bio.c
19
bio.c
|
@ -102,37 +102,28 @@ bget(uint dev, uint sector)
|
||||||
struct buf*
|
struct buf*
|
||||||
bread(uint dev, uint sector)
|
bread(uint dev, uint sector)
|
||||||
{
|
{
|
||||||
void *c;
|
|
||||||
struct buf *b;
|
struct buf *b;
|
||||||
extern struct spinlock ide_lock;
|
|
||||||
|
|
||||||
b = bget(dev, sector);
|
b = bget(dev, sector);
|
||||||
if(b->flags & B_VALID)
|
if(b->flags & B_VALID)
|
||||||
return b;
|
return b;
|
||||||
|
|
||||||
acquire(&ide_lock);
|
ide_rw(dev & 0xff, sector, b->data, 1, 1);
|
||||||
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
|
|
||||||
sleep(c, &ide_lock);
|
|
||||||
ide_finish(c);
|
|
||||||
b->flags |= B_VALID;
|
b->flags |= B_VALID;
|
||||||
release(&ide_lock);
|
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write buf's contents to disk.
|
// Write buf's contents to disk.
|
||||||
|
// Must be locked.
|
||||||
void
|
void
|
||||||
bwrite(struct buf *b, uint sector)
|
bwrite(struct buf *b, uint sector)
|
||||||
{
|
{
|
||||||
void *c;
|
if((b->flags & B_BUSY) == 0)
|
||||||
extern struct spinlock ide_lock;
|
panic("bwrite");
|
||||||
|
|
||||||
acquire(&ide_lock);
|
ide_rw(b->dev & 0xff, sector, b->data, 1, 0);
|
||||||
c = ide_start_rw(b->dev & 0xff, sector, b->data, 1, 0);
|
|
||||||
sleep(c, &ide_lock);
|
|
||||||
ide_finish(c);
|
|
||||||
b->flags |= B_VALID;
|
b->flags |= B_VALID;
|
||||||
release(&ide_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release the buffer buf.
|
// Release the buffer buf.
|
||||||
|
|
|
@ -409,7 +409,7 @@ console_init()
|
||||||
devsw[CONSOLE].write = console_write;
|
devsw[CONSOLE].write = console_write;
|
||||||
devsw[CONSOLE].read = console_read;
|
devsw[CONSOLE].read = console_read;
|
||||||
|
|
||||||
irq_setmask_8259A(irq_mask_8259A & ~(1 << IRQ_KBD));
|
irq_enable(IRQ_KBD);
|
||||||
ioapic_enable(IRQ_KBD, 0);
|
ioapic_enable(IRQ_KBD, 0);
|
||||||
|
|
||||||
use_console_lock = 1;
|
use_console_lock = 1;
|
||||||
|
|
6
defs.h
6
defs.h
|
@ -49,9 +49,8 @@ int argptr(int, char**, int);
|
||||||
int argstr(int, char**);
|
int argstr(int, char**);
|
||||||
|
|
||||||
// picirq.c
|
// picirq.c
|
||||||
extern ushort irq_mask_8259A;
|
|
||||||
void pic_init(void);
|
void pic_init(void);
|
||||||
void irq_setmask_8259A(ushort);
|
void irq_enable(int);
|
||||||
|
|
||||||
// 8253pit.c
|
// 8253pit.c
|
||||||
void pit8253_timerinit(void);
|
void pit8253_timerinit(void);
|
||||||
|
@ -109,8 +108,7 @@ void fileincref(struct file*);
|
||||||
// ide.c
|
// ide.c
|
||||||
void ide_init(void);
|
void ide_init(void);
|
||||||
void ide_intr(void);
|
void ide_intr(void);
|
||||||
void* ide_start_rw(int, uint, void*, uint, int);
|
void ide_rw(int, uint, void*, uint, int);
|
||||||
int ide_finish(void*);
|
|
||||||
|
|
||||||
// bio.c
|
// bio.c
|
||||||
void binit(void);
|
void binit(void);
|
||||||
|
|
64
ide.c
64
ide.c
|
@ -31,15 +31,16 @@ struct ide_request {
|
||||||
uint read;
|
uint read;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ide_request request[NREQUEST];
|
static struct ide_request request[NREQUEST];
|
||||||
int head, tail;
|
static int head, tail;
|
||||||
struct spinlock ide_lock;
|
static struct spinlock ide_lock;
|
||||||
|
|
||||||
int disk_1_present;
|
static int disk_1_present;
|
||||||
int disk_channel;
|
static int disk_queue;
|
||||||
|
|
||||||
int ide_probe_disk1(void);
|
static int ide_probe_disk1(void);
|
||||||
|
|
||||||
|
// Wait for IDE disk to become ready.
|
||||||
static int
|
static int
|
||||||
ide_wait_ready(int check_error)
|
ide_wait_ready(int check_error)
|
||||||
{
|
{
|
||||||
|
@ -57,12 +58,13 @@ void
|
||||||
ide_init(void)
|
ide_init(void)
|
||||||
{
|
{
|
||||||
initlock(&ide_lock, "ide");
|
initlock(&ide_lock, "ide");
|
||||||
irq_setmask_8259A(irq_mask_8259A & ~(1 << IRQ_IDE));
|
irq_enable(IRQ_IDE);
|
||||||
ioapic_enable (IRQ_IDE, ncpu - 1);
|
ioapic_enable(IRQ_IDE, ncpu - 1);
|
||||||
ide_wait_ready(0);
|
ide_wait_ready(0);
|
||||||
disk_1_present = ide_probe_disk1();
|
disk_1_present = ide_probe_disk1();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interrupt handler - wake up the request that just finished.
|
||||||
void
|
void
|
||||||
ide_intr(void)
|
ide_intr(void)
|
||||||
{
|
{
|
||||||
|
@ -71,7 +73,8 @@ ide_intr(void)
|
||||||
release(&ide_lock);
|
release(&ide_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
// Probe to see if disk 1 exists (we assume disk 0 exists).
|
||||||
|
static int
|
||||||
ide_probe_disk1(void)
|
ide_probe_disk1(void)
|
||||||
{
|
{
|
||||||
int r, x;
|
int r, x;
|
||||||
|
@ -92,7 +95,8 @@ ide_probe_disk1(void)
|
||||||
return x < 1000;
|
return x < 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// Start the next request in the queue.
|
||||||
|
static void
|
||||||
ide_start_request (void)
|
ide_start_request (void)
|
||||||
{
|
{
|
||||||
struct ide_request *r;
|
struct ide_request *r;
|
||||||
|
@ -115,16 +119,20 @@ ide_start_request (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
// Run an entire disk operation.
|
||||||
ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
|
void
|
||||||
|
ide_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
|
||||||
{
|
{
|
||||||
struct ide_request *r;
|
struct ide_request *r;
|
||||||
|
|
||||||
if(diskno && !disk_1_present)
|
if(diskno && !disk_1_present)
|
||||||
panic("ide disk 1 not present");
|
panic("ide disk 1 not present");
|
||||||
|
|
||||||
|
acquire(&ide_lock);
|
||||||
|
|
||||||
|
// Add request to queue.
|
||||||
while((head + 1) % NREQUEST == tail)
|
while((head + 1) % NREQUEST == tail)
|
||||||
sleep(&disk_channel, &ide_lock);
|
sleep(&disk_queue, &ide_lock);
|
||||||
|
|
||||||
r = &request[head];
|
r = &request[head];
|
||||||
r->secno = secno;
|
r->secno = secno;
|
||||||
|
@ -132,35 +140,29 @@ ide_start_rw(int diskno, uint secno, void *addr, uint nsecs, int read)
|
||||||
r->nsecs = nsecs;
|
r->nsecs = nsecs;
|
||||||
r->diskno = diskno;
|
r->diskno = diskno;
|
||||||
r->read = read;
|
r->read = read;
|
||||||
|
|
||||||
head = (head + 1) % NREQUEST;
|
head = (head + 1) % NREQUEST;
|
||||||
|
|
||||||
|
// Start request if necessary.
|
||||||
ide_start_request();
|
ide_start_request();
|
||||||
|
|
||||||
return r;
|
// Wait for request to finish.
|
||||||
}
|
sleep(r, &ide_lock);
|
||||||
|
|
||||||
int
|
// Finish request.
|
||||||
ide_finish(void *c)
|
if(read){
|
||||||
{
|
if(ide_wait_ready(1) >= 0)
|
||||||
int r;
|
insl(0x1F0, addr, 512/4);
|
||||||
struct ide_request *req = (struct ide_request*) c;
|
|
||||||
|
|
||||||
if(req->read) {
|
|
||||||
if((r = ide_wait_ready(1)) >= 0)
|
|
||||||
insl(0x1F0, req->addr, 512/4);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((head + 1) % NREQUEST == tail) {
|
|
||||||
wakeup(&disk_channel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove request from queue.
|
||||||
|
if((head + 1) % NREQUEST == tail)
|
||||||
|
wakeup(&disk_queue);
|
||||||
tail = (tail + 1) % NREQUEST;
|
tail = (tail + 1) % NREQUEST;
|
||||||
ide_start_request();
|
|
||||||
|
|
||||||
return 0;
|
release(&ide_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Synchronous disk write.
|
||||||
int
|
int
|
||||||
ide_write(int diskno, uint secno, const void *src, uint nsecs)
|
ide_write(int diskno, uint secno, const void *src, uint nsecs)
|
||||||
{
|
{
|
||||||
|
|
10
picirq.c
10
picirq.c
|
@ -11,9 +11,9 @@
|
||||||
|
|
||||||
// Current IRQ mask.
|
// Current IRQ mask.
|
||||||
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
|
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
|
||||||
ushort irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE);
|
static ushort irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE);
|
||||||
|
|
||||||
void
|
static void
|
||||||
irq_setmask_8259A(ushort mask)
|
irq_setmask_8259A(ushort mask)
|
||||||
{
|
{
|
||||||
irq_mask_8259A = mask;
|
irq_mask_8259A = mask;
|
||||||
|
@ -22,6 +22,12 @@ irq_setmask_8259A(ushort mask)
|
||||||
outb(IO_PIC2+1, (char)(mask >> 8));
|
outb(IO_PIC2+1, (char)(mask >> 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
irq_enable(int irq)
|
||||||
|
{
|
||||||
|
irq_setmask_8259A(irq_mask_8259A & ~(1<<irq));
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the 8259A interrupt controllers.
|
// Initialize the 8259A interrupt controllers.
|
||||||
void
|
void
|
||||||
pic_init(void)
|
pic_init(void)
|
||||||
|
|
Loading…
Reference in a new issue