checkpoint
This commit is contained in:
		
							parent
							
								
									be0a7eacda
								
							
						
					
					
						commit
						ae6e8aa730
					
				
					 5 changed files with 228 additions and 7 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \
 | 
					OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \
 | 
				
			||||||
       syscall.o
 | 
					       syscall.o ide.o picirq.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CC = i386-jos-elf-gcc
 | 
					CC = i386-jos-elf-gcc
 | 
				
			||||||
LD = i386-jos-elf-ld
 | 
					LD = i386-jos-elf-ld
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								defs.h
									
										
									
									
									
								
							| 
						 | 
					@ -24,3 +24,7 @@ void * memset(void *dst, int c, unsigned n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// syscall.c
 | 
					// syscall.c
 | 
				
			||||||
void syscall(void);
 | 
					void syscall(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// picirq.c
 | 
				
			||||||
 | 
					void irq_setmask_8259A(uint16_t mask);
 | 
				
			||||||
 | 
					void pic_init(void);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										117
									
								
								ide.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								ide.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,117 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Minimal PIO-based (non-interrupt-driven) IDE driver code.
 | 
				
			||||||
 | 
					 * For information about what all this IDE/ATA magic means,
 | 
				
			||||||
 | 
					 * see the materials available on the class references page.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "types.h"
 | 
				
			||||||
 | 
					#include "param.h"
 | 
				
			||||||
 | 
					#include "mmu.h"
 | 
				
			||||||
 | 
					#include "proc.h"
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					#include "x86.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IDE_BSY		0x80
 | 
				
			||||||
 | 
					#define IDE_DRDY	0x40
 | 
				
			||||||
 | 
					#define IDE_DF		0x20
 | 
				
			||||||
 | 
					#define IDE_ERR		0x01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int diskno = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					ide_wait_ready(int check_error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
 | 
				
			||||||
 | 
							/* do nothing */;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					ide_probe_disk1(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r, x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// wait for Device 0 to be ready
 | 
				
			||||||
 | 
						ide_wait_ready(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// switch to Device 1
 | 
				
			||||||
 | 
						outb(0x1F6, 0xE0 | (1<<4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// check for Device 1 to be ready for a while
 | 
				
			||||||
 | 
						for (x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
 | 
				
			||||||
 | 
							/* do nothing */;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// switch back to Device 0
 | 
				
			||||||
 | 
						outb(0x1F6, 0xE0 | (0<<4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cprintf("Device 1 presence: %d\n", (x < 1000));
 | 
				
			||||||
 | 
						return (x < 1000);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					ide_set_disk(int d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (d != 0 && d != 1)
 | 
				
			||||||
 | 
							panic("bad disk number");
 | 
				
			||||||
 | 
						diskno = d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					ide_read(uint32_t secno, void *dst, unsigned nsecs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(nsecs > 256)
 | 
				
			||||||
 | 
					          panic("ide_read");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ide_wait_ready(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        outb(0x3f6, 0);
 | 
				
			||||||
 | 
						outb(0x1F2, nsecs);
 | 
				
			||||||
 | 
						outb(0x1F3, secno & 0xFF);
 | 
				
			||||||
 | 
						outb(0x1F4, (secno >> 8) & 0xFF);
 | 
				
			||||||
 | 
						outb(0x1F5, (secno >> 16) & 0xFF);
 | 
				
			||||||
 | 
						outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
 | 
				
			||||||
 | 
						outb(0x1F7, 0x20);	// CMD 0x20 means read sector
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        sleep(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (; nsecs > 0; nsecs--, dst += 512) {
 | 
				
			||||||
 | 
							if ((r = ide_wait_ready(1)) < 0)
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
							insl(0x1F0, dst, 512/4);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					ide_write(uint32_t secno, const void *src, unsigned nsecs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int r;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					        if(nsecs > 256)
 | 
				
			||||||
 | 
					          panic("ide_write");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ide_wait_ready(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						outb(0x1F2, nsecs);
 | 
				
			||||||
 | 
						outb(0x1F3, secno & 0xFF);
 | 
				
			||||||
 | 
						outb(0x1F4, (secno >> 8) & 0xFF);
 | 
				
			||||||
 | 
						outb(0x1F5, (secno >> 16) & 0xFF);
 | 
				
			||||||
 | 
						outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
 | 
				
			||||||
 | 
						outb(0x1F7, 0x30);	// CMD 0x30 means write sector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (; nsecs > 0; nsecs--, src += 512) {
 | 
				
			||||||
 | 
							if ((r = ide_wait_ready(1)) < 0)
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
							outsl(0x1F0, src, 512/4);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								main.c
									
										
									
									
									
								
							| 
						 | 
					@ -9,6 +9,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern char edata[], end[];
 | 
					extern char edata[], end[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char buf[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
main()
 | 
					main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -18,16 +20,11 @@ main()
 | 
				
			||||||
  // clear BSS
 | 
					  // clear BSS
 | 
				
			||||||
  memset(edata, 0, end - edata);
 | 
					  memset(edata, 0, end - edata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // partially initizialize PIC
 | 
					 | 
				
			||||||
  outb(0x20+1, 0xFF); // IO_PIC1
 | 
					 | 
				
			||||||
  outb(0xA0+1, 0xFF); // IO_PIC2
 | 
					 | 
				
			||||||
  outb(0x20, 0x11);
 | 
					 | 
				
			||||||
  outb(0x20+1, 32);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  cprintf("\nxV6\n\n");
 | 
					  cprintf("\nxV6\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  kinit(); // physical memory allocator
 | 
					  kinit(); // physical memory allocator
 | 
				
			||||||
  tinit(); // traps and interrupts
 | 
					  tinit(); // traps and interrupts
 | 
				
			||||||
 | 
					  pic_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // create fake process zero
 | 
					  // create fake process zero
 | 
				
			||||||
  p = &proc[0];
 | 
					  p = &proc[0];
 | 
				
			||||||
| 
						 | 
					@ -46,6 +43,16 @@ main()
 | 
				
			||||||
  p->ppid = 0;
 | 
					  p->ppid = 0;
 | 
				
			||||||
  setupsegs(p);
 | 
					  setupsegs(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // turn on interrupts
 | 
				
			||||||
 | 
					  write_eflags(read_eflags() | FL_IF);
 | 
				
			||||||
 | 
					  irq_setmask_8259A(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 1
 | 
				
			||||||
 | 
					  ide_read(0, buf, 1);
 | 
				
			||||||
 | 
					  cprintf("sec0.0 %x\n", buf[0] & 0xff);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
  p = newproc();
 | 
					  p = newproc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  i = 0;
 | 
					  i = 0;
 | 
				
			||||||
| 
						 | 
					@ -73,6 +80,7 @@ main()
 | 
				
			||||||
  p->mem[i++] = T_SYSCALL;
 | 
					  p->mem[i++] = T_SYSCALL;
 | 
				
			||||||
  p->tf->tf_eip = 0;
 | 
					  p->tf->tf_eip = 0;
 | 
				
			||||||
  p->tf->tf_esp = p->sz;
 | 
					  p->tf->tf_esp = p->sz;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  swtch();
 | 
					  swtch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										92
									
								
								picirq.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								picirq.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,92 @@
 | 
				
			||||||
 | 
					/* See COPYRIGHT for copyright information. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "types.h"
 | 
				
			||||||
 | 
					#include "x86.h"
 | 
				
			||||||
 | 
					#include "defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_IRQS	16	// Number of IRQs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// I/O Addresses of the two 8259A programmable interrupt controllers
 | 
				
			||||||
 | 
					#define IO_PIC1		0x20	// Master (IRQs 0-7)
 | 
				
			||||||
 | 
					#define IO_PIC2		0xA0	// Slave (IRQs 8-15)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IRQ_SLAVE	2	// IRQ at which slave connects to master
 | 
				
			||||||
 | 
					#define IRQ_OFFSET	32	// IRQ 0 corresponds to int IRQ_OFFSET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Current IRQ mask.
 | 
				
			||||||
 | 
					// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
 | 
				
			||||||
 | 
					uint16_t irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE);
 | 
				
			||||||
 | 
					static int didinit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Initialize the 8259A interrupt controllers. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					pic_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						didinit = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// mask all interrupts
 | 
				
			||||||
 | 
						outb(IO_PIC1+1, 0xFF);
 | 
				
			||||||
 | 
						outb(IO_PIC2+1, 0xFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set up master (8259A-1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ICW1:  0001g0hi
 | 
				
			||||||
 | 
						//    g:  0 = edge triggering, 1 = level triggering
 | 
				
			||||||
 | 
						//    h:  0 = cascaded PICs, 1 = master only
 | 
				
			||||||
 | 
						//    i:  0 = no ICW4, 1 = ICW4 required
 | 
				
			||||||
 | 
						outb(IO_PIC1, 0x11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ICW2:  Vector offset
 | 
				
			||||||
 | 
						outb(IO_PIC1+1, IRQ_OFFSET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ICW3:  bit mask of IR lines connected to slave PICs (master PIC),
 | 
				
			||||||
 | 
						//        3-bit No of IR line at which slave connects to master(slave PIC).
 | 
				
			||||||
 | 
						outb(IO_PIC1+1, 1<<IRQ_SLAVE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ICW4:  000nbmap
 | 
				
			||||||
 | 
						//    n:  1 = special fully nested mode
 | 
				
			||||||
 | 
						//    b:  1 = buffered mode
 | 
				
			||||||
 | 
						//    m:  0 = slave PIC, 1 = master PIC
 | 
				
			||||||
 | 
						//	  (ignored when b is 0, as the master/slave role
 | 
				
			||||||
 | 
						//	  can be hardwired).
 | 
				
			||||||
 | 
						//    a:  1 = Automatic EOI mode
 | 
				
			||||||
 | 
						//    p:  0 = MCS-80/85 mode, 1 = intel x86 mode
 | 
				
			||||||
 | 
						outb(IO_PIC1+1, 0x3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set up slave (8259A-2)
 | 
				
			||||||
 | 
						outb(IO_PIC2, 0x11);			// ICW1
 | 
				
			||||||
 | 
						outb(IO_PIC2+1, IRQ_OFFSET + 8);	// ICW2
 | 
				
			||||||
 | 
						outb(IO_PIC2+1, IRQ_SLAVE);		// ICW3
 | 
				
			||||||
 | 
						// NB Automatic EOI mode doesn't tend to work on the slave.
 | 
				
			||||||
 | 
						// Linux source code says it's "to be investigated".
 | 
				
			||||||
 | 
						outb(IO_PIC2+1, 0x01);			// ICW4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// OCW3:  0ef01prs
 | 
				
			||||||
 | 
						//   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
 | 
				
			||||||
 | 
						//    p:  0 = no polling, 1 = polling mode
 | 
				
			||||||
 | 
						//   rs:  0x = NOP, 10 = read IRR, 11 = read ISR
 | 
				
			||||||
 | 
						outb(IO_PIC1, 0x68);             /* clear specific mask */
 | 
				
			||||||
 | 
						outb(IO_PIC1, 0x0a);             /* read IRR by default */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						outb(IO_PIC2, 0x68);               /* OCW3 */
 | 
				
			||||||
 | 
						outb(IO_PIC2, 0x0a);               /* OCW3 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (irq_mask_8259A != 0xFFFF)
 | 
				
			||||||
 | 
							irq_setmask_8259A(irq_mask_8259A);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					irq_setmask_8259A(uint16_t mask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						irq_mask_8259A = mask;
 | 
				
			||||||
 | 
						if (!didinit)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						outb(IO_PIC1+1, (char)mask);
 | 
				
			||||||
 | 
						outb(IO_PIC2+1, (char)(mask >> 8));
 | 
				
			||||||
 | 
						cprintf("enabled interrupts:");
 | 
				
			||||||
 | 
						for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
							if (~mask & (1<<i))
 | 
				
			||||||
 | 
								cprintf(" %d", i);
 | 
				
			||||||
 | 
						cprintf("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue