no /* */ comments
This commit is contained in:
		
							parent
							
								
									9e9bcaf143
								
							
						
					
					
						commit
						f552738889
					
				
					 22 changed files with 347 additions and 371 deletions
				
			
		
							
								
								
									
										57
									
								
								bootmain.c
									
										
									
									
									
								
							
							
						
						
									
										57
									
								
								bootmain.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,34 +1,31 @@
 | 
				
			||||||
#include "types.h"
 | 
					#include "types.h"
 | 
				
			||||||
#include "elf.h"
 | 
					#include "elf.h"
 | 
				
			||||||
#include "x86.h"
 | 
					#include "x86.h"
 | 
				
			||||||
 | 
					// This a dirt simple boot loader, whose sole job is to boot
 | 
				
			||||||
/**********************************************************************
 | 
					// an elf kernel image from the first IDE hard disk.
 | 
				
			||||||
 * This a dirt simple boot loader, whose sole job is to boot
 | 
					//
 | 
				
			||||||
 * an elf kernel image from the first IDE hard disk.
 | 
					// DISK LAYOUT
 | 
				
			||||||
 *
 | 
					//  * This program(boot.S and main.c) is the bootloader.  It should
 | 
				
			||||||
 * DISK LAYOUT
 | 
					//    be stored in the first sector of the disk.
 | 
				
			||||||
 *  * This program(boot.S and main.c) is the bootloader.  It should
 | 
					//
 | 
				
			||||||
 *    be stored in the first sector of the disk.
 | 
					//  * The 2nd sector onward holds the kernel image.
 | 
				
			||||||
 *
 | 
					//
 | 
				
			||||||
 *  * The 2nd sector onward holds the kernel image.
 | 
					//  * The kernel image must be in ELF format.
 | 
				
			||||||
 *
 | 
					//
 | 
				
			||||||
 *  * The kernel image must be in ELF format.
 | 
					// BOOT UP STEPS
 | 
				
			||||||
 *
 | 
					//  * when the CPU boots it loads the BIOS into memory and executes it
 | 
				
			||||||
 * BOOT UP STEPS
 | 
					//
 | 
				
			||||||
 *  * when the CPU boots it loads the BIOS into memory and executes it
 | 
					//  * the BIOS intializes devices, sets of the interrupt routines, and
 | 
				
			||||||
 *
 | 
					//    reads the first sector of the boot device(e.g., hard-drive)
 | 
				
			||||||
 *  * the BIOS intializes devices, sets of the interrupt routines, and
 | 
					//    into memory and jumps to it.
 | 
				
			||||||
 *    reads the first sector of the boot device(e.g., hard-drive)
 | 
					//
 | 
				
			||||||
 *    into memory and jumps to it.
 | 
					//  * Assuming this boot loader is stored in the first sector of the
 | 
				
			||||||
 *
 | 
					//    hard-drive, this code takes over...
 | 
				
			||||||
 *  * Assuming this boot loader is stored in the first sector of the
 | 
					//
 | 
				
			||||||
 *    hard-drive, this code takes over...
 | 
					//  * control starts in bootloader.S -- which sets up protected mode,
 | 
				
			||||||
 *
 | 
					//    and a stack so C code then run, then calls cmain()
 | 
				
			||||||
 *  * control starts in bootloader.S -- which sets up protected mode,
 | 
					//
 | 
				
			||||||
 *    and a stack so C code then run, then calls cmain()
 | 
					//  * cmain() in this file takes over, reads in the kernel and jumps to it.
 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *  * cmain() in this file takes over, reads in the kernel and jumps to it.
 | 
					 | 
				
			||||||
 **********************************************************************/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SECTSIZE  512
 | 
					#define SECTSIZE  512
 | 
				
			||||||
#define ELFHDR    ((struct elfhdr*) 0x10000) // scratch space
 | 
					#define ELFHDR    ((struct elfhdr*) 0x10000) // scratch space
 | 
				
			||||||
| 
						 | 
					@ -62,7 +59,7 @@ bad:
 | 
				
			||||||
  outw(0x8A00, 0x8A00);
 | 
					  outw(0x8A00, 0x8A00);
 | 
				
			||||||
  outw(0x8A00, 0x8E00);
 | 
					  outw(0x8A00, 0x8E00);
 | 
				
			||||||
  while(1)
 | 
					  while(1)
 | 
				
			||||||
    /* do nothing */;
 | 
					    ;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
 | 
					// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
 | 
				
			||||||
| 
						 | 
					@ -96,7 +93,7 @@ waitdisk(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  // wait for disk reaady
 | 
					  // wait for disk reaady
 | 
				
			||||||
  while((inb(0x1F7) & 0xC0) != 0x40)
 | 
					  while((inb(0x1F7) & 0xC0) != 0x40)
 | 
				
			||||||
    /* do nothing */;
 | 
					    ;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										71
									
								
								console.c
									
										
									
									
									
								
							
							
						
						
									
										71
									
								
								console.c
									
										
									
									
									
								
							| 
						 | 
					@ -10,11 +10,9 @@ struct spinlock console_lock;
 | 
				
			||||||
int panicked = 0;
 | 
					int panicked = 0;
 | 
				
			||||||
int use_console_lock = 0;
 | 
					int use_console_lock = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Copy console output to parallel port, which you can tell
 | 
				
			||||||
 * copy console output to parallel port, which you can tell
 | 
					// .bochsrc to copy to the stdout:
 | 
				
			||||||
 * .bochsrc to copy to the stdout:
 | 
					//   parport1: enabled=1, file="/dev/stdout"
 | 
				
			||||||
 * parport1: enabled=1, file="/dev/stdout"
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
lpt_putc(int c)
 | 
					lpt_putc(int c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -97,9 +95,7 @@ printint(int xx, int base, int sgn)
 | 
				
			||||||
    cons_putc(buf[i]);
 | 
					    cons_putc(buf[i]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Print to the console. only understands %d, %x, %p, %s.
 | 
				
			||||||
 * print to the console. only understands %d, %x, %p, %s.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cprintf(char *fmt, ...)
 | 
					cprintf(char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -182,10 +178,10 @@ console_write(int minor, char *buf, int n)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This is i8042reg.h + kbdreg.h from NetBSD. */
 | 
					// This is i8042reg.h + kbdreg.h from NetBSD.
 | 
				
			||||||
#define KBSTATP         0x64    /* kbd controller status port(I) */
 | 
					#define KBSTATP         0x64    // kbd controller status port(I)
 | 
				
			||||||
#define KBS_DIB         0x01    /* kbd data in buffer */
 | 
					#define KBS_DIB         0x01    // kbd data in buffer
 | 
				
			||||||
#define KBDATAP         0x60    /* kbd data port(I) */
 | 
					#define KBDATAP         0x60    // kbd data port(I)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NO              0
 | 
					#define NO              0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -241,12 +237,18 @@ static uchar normalmap[256] =
 | 
				
			||||||
  NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',  // 0x40
 | 
					  NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',  // 0x40
 | 
				
			||||||
  '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',
 | 
					  '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',
 | 
				
			||||||
  '2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,   // 0x50
 | 
					  '2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,   // 0x50
 | 
				
			||||||
  [0x97] KEY_HOME,  [0x9C] '\n' /*KP_Enter*/,
 | 
					  [0x97] KEY_HOME,
 | 
				
			||||||
  [0xB5] '/' /*KP_Div*/,  [0xC8] KEY_UP,
 | 
					  [0x9C] '\n',      // KP_Enter
 | 
				
			||||||
  [0xC9] KEY_PGUP,  [0xCB] KEY_LF,
 | 
					  [0xB5] '/',       // KP_Div
 | 
				
			||||||
  [0xCD] KEY_RT,    [0xCF] KEY_END,
 | 
					  [0xC8] KEY_UP,
 | 
				
			||||||
  [0xD0] KEY_DN,    [0xD1] KEY_PGDN,
 | 
					  [0xC9] KEY_PGUP,
 | 
				
			||||||
  [0xD2] KEY_INS,   [0xD3] KEY_DEL
 | 
					  [0xCB] KEY_LF,
 | 
				
			||||||
 | 
					  [0xCD] KEY_RT,
 | 
				
			||||||
 | 
					  [0xCF] KEY_END,
 | 
				
			||||||
 | 
					  [0xD0] KEY_DN,
 | 
				
			||||||
 | 
					  [0xD1] KEY_PGDN,
 | 
				
			||||||
 | 
					  [0xD2] KEY_INS,
 | 
				
			||||||
 | 
					  [0xD3] KEY_DEL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uchar shiftmap[256] =
 | 
					static uchar shiftmap[256] =
 | 
				
			||||||
| 
						 | 
					@ -262,12 +264,18 @@ static uchar shiftmap[256] =
 | 
				
			||||||
  NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',  // 0x40
 | 
					  NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',  // 0x40
 | 
				
			||||||
  '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',
 | 
					  '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',
 | 
				
			||||||
  '2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,   // 0x50
 | 
					  '2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,   // 0x50
 | 
				
			||||||
  [0x97] KEY_HOME,  [0x9C] '\n' /*KP_Enter*/,
 | 
					  [0x97] KEY_HOME,
 | 
				
			||||||
  [0xB5] '/' /*KP_Div*/,  [0xC8] KEY_UP,
 | 
					  [0x9C] '\n',      // KP_Enter
 | 
				
			||||||
  [0xC9] KEY_PGUP,  [0xCB] KEY_LF,
 | 
					  [0xB5] '/',       // KP_Div
 | 
				
			||||||
  [0xCD] KEY_RT,    [0xCF] KEY_END,
 | 
					  [0xC8] KEY_UP,
 | 
				
			||||||
  [0xD0] KEY_DN,    [0xD1] KEY_PGDN,
 | 
					  [0xC9] KEY_PGUP,
 | 
				
			||||||
  [0xD2] KEY_INS,   [0xD3] KEY_DEL
 | 
					  [0xCB] KEY_LF,
 | 
				
			||||||
 | 
					  [0xCD] KEY_RT,
 | 
				
			||||||
 | 
					  [0xCF] KEY_END,
 | 
				
			||||||
 | 
					  [0xD0] KEY_DN,
 | 
				
			||||||
 | 
					  [0xD1] KEY_PGDN,
 | 
				
			||||||
 | 
					  [0xD2] KEY_INS,
 | 
				
			||||||
 | 
					  [0xD3] KEY_DEL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define C(x) (x - '@')
 | 
					#define C(x) (x - '@')
 | 
				
			||||||
| 
						 | 
					@ -282,11 +290,16 @@ static uchar ctlmap[256] =
 | 
				
			||||||
  NO,      NO,      NO,      C('\\'), C('Z'),  C('X'),  C('C'),  C('V'),
 | 
					  NO,      NO,      NO,      C('\\'), C('Z'),  C('X'),  C('C'),  C('V'),
 | 
				
			||||||
  C('B'),  C('N'),  C('M'),  NO,      NO,      C('/'),  NO,      NO,
 | 
					  C('B'),  C('N'),  C('M'),  NO,      NO,      C('/'),  NO,      NO,
 | 
				
			||||||
  [0x97] KEY_HOME,
 | 
					  [0x97] KEY_HOME,
 | 
				
			||||||
  [0xB5] C('/'),    [0xC8] KEY_UP,
 | 
					  [0xB5] C('/'),    // KP_Div
 | 
				
			||||||
  [0xC9] KEY_PGUP,  [0xCB] KEY_LF,
 | 
					  [0xC8] KEY_UP,
 | 
				
			||||||
  [0xCD] KEY_RT,    [0xCF] KEY_END,
 | 
					  [0xC9] KEY_PGUP,
 | 
				
			||||||
  [0xD0] KEY_DN,    [0xD1] KEY_PGDN,
 | 
					  [0xCB] KEY_LF,
 | 
				
			||||||
  [0xD2] KEY_INS,   [0xD3] KEY_DEL
 | 
					  [0xCD] KEY_RT,
 | 
				
			||||||
 | 
					  [0xCF] KEY_END,
 | 
				
			||||||
 | 
					  [0xD0] KEY_DN,
 | 
				
			||||||
 | 
					  [0xD1] KEY_PGDN,
 | 
				
			||||||
 | 
					  [0xD2] KEY_INS,
 | 
				
			||||||
 | 
					  [0xD3] KEY_DEL
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uchar *charcode[4] = {
 | 
					static uchar *charcode[4] = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								elf.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								elf.h
									
										
									
									
									
								
							| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
// format of an ELF executable file
 | 
					// format of an ELF executable file
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ELF_MAGIC 0x464C457FU	/* "\x7FELF" in little endian */
 | 
					#define ELF_MAGIC 0x464C457FU	// "\x7FELF" in little endian
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct elfhdr {
 | 
					struct elfhdr {
 | 
				
			||||||
  uint magic;  // must equal ELF_MAGIC
 | 
					  uint magic;  // must equal ELF_MAGIC
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								fd.c
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								fd.c
									
										
									
									
									
								
							| 
						 | 
					@ -22,9 +22,7 @@ fd_init(void)
 | 
				
			||||||
  initlock(&fd_table_lock, "fd_table");
 | 
					  initlock(&fd_table_lock, "fd_table");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Allocate a file descriptor number for curproc.
 | 
				
			||||||
 * allocate a file descriptor number for curproc.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
fd_ualloc(void)
 | 
					fd_ualloc(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -36,9 +34,7 @@ fd_ualloc(void)
 | 
				
			||||||
  return -1;
 | 
					  return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Allocate a file descriptor structure
 | 
				
			||||||
 * allocate a file descriptor structure
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct fd*
 | 
					struct fd*
 | 
				
			||||||
fd_alloc(void)
 | 
					fd_alloc(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -57,9 +53,8 @@ fd_alloc(void)
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Write to file descriptor;
 | 
				
			||||||
 * addr is a kernel address, pointing into some process's p->mem.
 | 
					// addr is a kernel address, pointing into some process's p->mem.
 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
fd_write(struct fd *fd, char *addr, int n)
 | 
					fd_write(struct fd *fd, char *addr, int n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -81,6 +76,7 @@ fd_write(struct fd *fd, char *addr, int n)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Read from file descriptor.
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
fd_read(struct fd *fd, char *addr, int n)
 | 
					fd_read(struct fd *fd, char *addr, int n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -101,6 +97,7 @@ fd_read(struct fd *fd, char *addr, int n)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Close file descriptor.
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
fd_close(struct fd *fd)
 | 
					fd_close(struct fd *fd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -128,6 +125,7 @@ fd_close(struct fd *fd)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get metadata about file descriptor.
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
fd_stat(struct fd *fd, struct stat *st)
 | 
					fd_stat(struct fd *fd, struct stat *st)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -140,6 +138,7 @@ fd_stat(struct fd *fd, struct stat *st)
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Increment file descriptor reference count.
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
fd_incref(struct fd *fd)
 | 
					fd_incref(struct fd *fd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								fs.c
									
										
									
									
									
								
							| 
						 | 
					@ -24,9 +24,7 @@ iinit(void)
 | 
				
			||||||
  initlock(&inode_table_lock, "inode_table");
 | 
					  initlock(&inode_table_lock, "inode_table");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Allocate a disk block.
 | 
				
			||||||
 * allocate a disk block
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static uint
 | 
					static uint
 | 
				
			||||||
balloc(uint dev)
 | 
					balloc(uint dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -90,11 +88,11 @@ bfree(int dev, uint b)
 | 
				
			||||||
  brelse(bp);
 | 
					  brelse(bp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Find the inode with number inum on device dev
 | 
				
			||||||
 * fetch an inode, from the in-core table if it's already
 | 
					// and return an in-memory copy.  Loads the inode
 | 
				
			||||||
 * in use, otherwise read from the disk.
 | 
					// from disk into the in-core table if necessary.
 | 
				
			||||||
 * returns an inode with busy set and incremented reference count.
 | 
					// The returned inode has busy set and has its ref count incremented.
 | 
				
			||||||
 */
 | 
					// Caller must iput the return value when done with it.
 | 
				
			||||||
struct inode*
 | 
					struct inode*
 | 
				
			||||||
iget(uint dev, uint inum)
 | 
					iget(uint dev, uint inum)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								ide.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								ide.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,6 +1,4 @@
 | 
				
			||||||
/*
 | 
					// Simple PIO-based (non-DMA) IDE driver code.
 | 
				
			||||||
 * Simple PIO-based (non-DMA) IDE driver code.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "types.h"
 | 
					#include "types.h"
 | 
				
			||||||
#include "param.h"
 | 
					#include "param.h"
 | 
				
			||||||
| 
						 | 
					@ -38,7 +36,7 @@ ide_wait_ready(int check_error)
 | 
				
			||||||
  int r;
 | 
					  int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while(((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
 | 
					  while(((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
 | 
				
			||||||
    /* do nothing */;
 | 
					    ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(check_error && (r & (IDE_DF|IDE_ERR)) != 0)
 | 
					  if(check_error && (r & (IDE_DF|IDE_ERR)) != 0)
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
| 
						 | 
					@ -75,7 +73,7 @@ ide_probe_disk1(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // check for Device 1 to be ready for a while
 | 
					  // check for Device 1 to be ready for a while
 | 
				
			||||||
  for(x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
 | 
					  for(x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
 | 
				
			||||||
    /* do nothing */;
 | 
					    ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // switch back to Device 0
 | 
					  // switch back to Device 0
 | 
				
			||||||
  outb(0x1F6, 0xE0 | (0<<4));
 | 
					  outb(0x1F6, 0xE0 | (0<<4));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								init.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								init.c
									
										
									
									
									
								
							| 
						 | 
					@ -4,7 +4,7 @@
 | 
				
			||||||
#include "fs.h"
 | 
					#include "fs.h"
 | 
				
			||||||
#include "fcntl.h"
 | 
					#include "fcntl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The initial user-level program */
 | 
					// init: The initial user-level program
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *sh_args[] = { "sh", 0 };
 | 
					char *sh_args[] = { "sh", 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										68
									
								
								ioapic.h
									
										
									
									
									
								
							
							
						
						
									
										68
									
								
								ioapic.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
#define IO_APIC_BASE   0xFEC00000   /* default physical locations of an IO APIC */
 | 
					#define IO_APIC_BASE   0xFEC00000   // default physical locations of an IO APIC
 | 
				
			||||||
#define IOAPIC_WINDOW        0x10   /* window register offset */
 | 
					#define IOAPIC_WINDOW        0x10   // window register offset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* constants relating to APIC ID registers */
 | 
					// Constants relating to APIC ID registers
 | 
				
			||||||
#define APIC_ID_MASK            0xff000000
 | 
					#define APIC_ID_MASK            0xff000000
 | 
				
			||||||
#define APIC_ID_SHIFT           24
 | 
					#define APIC_ID_SHIFT           24
 | 
				
			||||||
#define APIC_ID_CLUSTER         0xf0
 | 
					#define APIC_ID_CLUSTER         0xf0
 | 
				
			||||||
| 
						 | 
					@ -10,12 +10,12 @@
 | 
				
			||||||
#define APIC_MAX_INTRACLUSTER_ID 3
 | 
					#define APIC_MAX_INTRACLUSTER_ID 3
 | 
				
			||||||
#define APIC_ID_CLUSTER_SHIFT   4
 | 
					#define APIC_ID_CLUSTER_SHIFT   4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* fields in VER */
 | 
					// Fields in VER
 | 
				
			||||||
#define APIC_VER_VERSION        0x000000ff
 | 
					#define APIC_VER_VERSION        0x000000ff
 | 
				
			||||||
#define APIC_VER_MAXLVT         0x00ff0000
 | 
					#define APIC_VER_MAXLVT         0x00ff0000
 | 
				
			||||||
#define MAXLVTSHIFT             16
 | 
					#define MAXLVTSHIFT             16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Indexes into IO APIC */
 | 
					// Indexes into IO APIC
 | 
				
			||||||
#define IOAPIC_ID               0x00
 | 
					#define IOAPIC_ID               0x00
 | 
				
			||||||
#define IOAPIC_VER              0x01
 | 
					#define IOAPIC_VER              0x01
 | 
				
			||||||
#define IOAPIC_ARB              0x02
 | 
					#define IOAPIC_ARB              0x02
 | 
				
			||||||
| 
						 | 
					@ -45,46 +45,44 @@
 | 
				
			||||||
#define IOAPIC_REDTBL22         (IOAPIC_REDTBL+0x2c)
 | 
					#define IOAPIC_REDTBL22         (IOAPIC_REDTBL+0x2c)
 | 
				
			||||||
#define IOAPIC_REDTBL23         (IOAPIC_REDTBL+0x2e)
 | 
					#define IOAPIC_REDTBL23         (IOAPIC_REDTBL+0x2e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Fields in the IO APIC's redirection table entries
 | 
				
			||||||
 * fields in the IO APIC's redirection table entries
 | 
					#define IOART_DEST      APIC_ID_MASK    // broadcast addr: all APICs
 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define IOART_DEST      APIC_ID_MASK    /* broadcast addr: all APICs */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_RESV      0x00fe0000      /* reserved */
 | 
					#define IOART_RESV      0x00fe0000      // reserved
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_INTMASK   0x00010000      /* R/W: INTerrupt mask */
 | 
					#define IOART_INTMASK   0x00010000      // R/W: INTerrupt mask
 | 
				
			||||||
#define IOART_INTMCLR   0x00000000      /*       clear, allow INTs */
 | 
					#define IOART_INTMCLR   0x00000000      //       clear, allow INTs
 | 
				
			||||||
#define IOART_INTMSET   0x00010000      /*       set, inhibit INTs */
 | 
					#define IOART_INTMSET   0x00010000      //       set, inhibit INTs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_TRGRMOD   0x00008000      /* R/W: trigger mode */
 | 
					#define IOART_TRGRMOD   0x00008000      // R/W: trigger mode
 | 
				
			||||||
#define IOART_TRGREDG   0x00000000      /*       edge */
 | 
					#define IOART_TRGREDG   0x00000000      //       edge
 | 
				
			||||||
#define IOART_TRGRLVL   0x00008000      /*       level */
 | 
					#define IOART_TRGRLVL   0x00008000      //       level
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_REM_IRR   0x00004000      /* RO: remote IRR */
 | 
					#define IOART_REM_IRR   0x00004000      // RO: remote IRR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_INTPOL    0x00002000      /* R/W: INT input pin polarity */
 | 
					#define IOART_INTPOL    0x00002000      // R/W: INT input pin polarity
 | 
				
			||||||
#define IOART_INTAHI    0x00000000      /*      active high */
 | 
					#define IOART_INTAHI    0x00000000      //      active high
 | 
				
			||||||
#define IOART_INTALO    0x00002000      /*      active low */
 | 
					#define IOART_INTALO    0x00002000      //      active low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_DELIVS    0x00001000      /* RO: delivery status */
 | 
					#define IOART_DELIVS    0x00001000      // RO: delivery status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_DESTMOD   0x00000800      /* R/W: destination mode */
 | 
					#define IOART_DESTMOD   0x00000800      // R/W: destination mode
 | 
				
			||||||
#define IOART_DESTPHY   0x00000000      /*      physical */
 | 
					#define IOART_DESTPHY   0x00000000      //      physical
 | 
				
			||||||
#define IOART_DESTLOG   0x00000800      /*      logical */
 | 
					#define IOART_DESTLOG   0x00000800      //      logical
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_DELMOD    0x00000700      /* R/W: delivery mode */
 | 
					#define IOART_DELMOD    0x00000700      // R/W: delivery mode
 | 
				
			||||||
#define IOART_DELFIXED  0x00000000      /*       fixed */
 | 
					#define IOART_DELFIXED  0x00000000      //       fixed
 | 
				
			||||||
#define IOART_DELLOPRI  0x00000100      /*       lowest priority */
 | 
					#define IOART_DELLOPRI  0x00000100      //       lowest priority
 | 
				
			||||||
#define IOART_DELSMI    0x00000200      /*       System Management INT */
 | 
					#define IOART_DELSMI    0x00000200      //       System Management INT
 | 
				
			||||||
#define IOART_DELRSV1   0x00000300      /*       reserved */
 | 
					#define IOART_DELRSV1   0x00000300      //       reserved
 | 
				
			||||||
#define IOART_DELNMI    0x00000400      /*       NMI signal */
 | 
					#define IOART_DELNMI    0x00000400      //       NMI signal
 | 
				
			||||||
#define IOART_DELINIT   0x00000500      /*       INIT signal */
 | 
					#define IOART_DELINIT   0x00000500      //       INIT signal
 | 
				
			||||||
#define IOART_DELRSV2   0x00000600      /*       reserved */
 | 
					#define IOART_DELRSV2   0x00000600      //       reserved
 | 
				
			||||||
#define IOART_DELEXINT  0x00000700      /*       External INTerrupt */
 | 
					#define IOART_DELEXINT  0x00000700      //       External INTerrupt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IOART_INTVEC    0x000000ff      /* R/W: INTerrupt vector field */
 | 
					#define IOART_INTVEC    0x000000ff      // R/W: INTerrupt vector field
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* fields in VER */
 | 
					// Fields in VER
 | 
				
			||||||
#define IOART_VER_VERSION       0x000000ff
 | 
					#define IOART_VER_VERSION       0x000000ff
 | 
				
			||||||
#define IOART_VER_MAXREDIR      0x00ff0000
 | 
					#define IOART_VER_MAXREDIR      0x00ff0000
 | 
				
			||||||
#define MAXREDIRSHIFT           16
 | 
					#define MAXREDIRSHIFT           16
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								kalloc.c
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								kalloc.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,11 +1,9 @@
 | 
				
			||||||
/*
 | 
					// Physical memory allocator, intended to allocate
 | 
				
			||||||
 * physical memory allocator, intended to be used to allocate
 | 
					// memory for user processes. Allocates in 4096-byte "pages".
 | 
				
			||||||
 * memory for user processes. allocates in 4096-byte "pages".
 | 
					// Free list is kept sorted and combines adjacent pages into
 | 
				
			||||||
 * free list is sorted and combines adjacent pages into
 | 
					// long runs, to make it easier to allocate big segments.
 | 
				
			||||||
 * long runs, to make it easier to allocate big segments.
 | 
					// One reason the page size is 4k is that the x86 segment size
 | 
				
			||||||
 * one reason the page size is 4k is that the x86 segment size
 | 
					// granularity is 4k.
 | 
				
			||||||
 * granularity is 4k.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "param.h"
 | 
					#include "param.h"
 | 
				
			||||||
#include "types.h"
 | 
					#include "types.h"
 | 
				
			||||||
| 
						 | 
					@ -23,11 +21,10 @@ struct run {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
struct run *freelist;
 | 
					struct run *freelist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Initialize free list of physical pages.
 | 
				
			||||||
 * initialize free list of physical pages. this code
 | 
					// This code cheats by just considering one megabyte of
 | 
				
			||||||
 * cheats by just considering the one megabyte of pages
 | 
					// pages after _end.  Real systems would determine the
 | 
				
			||||||
 * after _end.
 | 
					// amount of memory available in the system and use it all.
 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
kinit(void)
 | 
					kinit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -95,11 +92,9 @@ kfree(char *cp, int len)
 | 
				
			||||||
  release(&kalloc_lock);
 | 
					  release(&kalloc_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Allocate n bytes of physical memory.
 | 
				
			||||||
 * allocate n bytes of physical memory.
 | 
					// Returns a kernel-segment pointer.
 | 
				
			||||||
 * returns a kernel-segment pointer.
 | 
					// Returns 0 if the memory cannot be allocated.
 | 
				
			||||||
 * returns 0 if there's no run that's big enough.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
char*
 | 
					char*
 | 
				
			||||||
kalloc(int n)
 | 
					kalloc(int n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										136
									
								
								lapic.c
									
										
									
									
									
								
							
							
						
						
									
										136
									
								
								lapic.c
									
										
									
									
									
								
							| 
						 | 
					@ -7,84 +7,84 @@
 | 
				
			||||||
#include "mmu.h"
 | 
					#include "mmu.h"
 | 
				
			||||||
#include "proc.h"
 | 
					#include "proc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {					/* Local APIC registers */
 | 
					enum {					// Local APIC registers
 | 
				
			||||||
  LAPIC_ID  = 0x0020,	/* ID */
 | 
					  LAPIC_ID  = 0x0020,	// ID
 | 
				
			||||||
  LAPIC_VER = 0x0030,	/* Version */
 | 
					  LAPIC_VER = 0x0030,	// Version
 | 
				
			||||||
  LAPIC_TPR = 0x0080,	/* Task Priority */
 | 
					  LAPIC_TPR = 0x0080,	// Task Priority
 | 
				
			||||||
  LAPIC_APR = 0x0090,	/* Arbitration Priority */
 | 
					  LAPIC_APR = 0x0090,	// Arbitration Priority
 | 
				
			||||||
  LAPIC_PPR = 0x00A0,	/* Processor Priority */
 | 
					  LAPIC_PPR = 0x00A0,	// Processor Priority
 | 
				
			||||||
  LAPIC_EOI = 0x00B0,	/* EOI */
 | 
					  LAPIC_EOI = 0x00B0,	// EOI
 | 
				
			||||||
  LAPIC_LDR = 0x00D0,	/* Logical Destination */
 | 
					  LAPIC_LDR = 0x00D0,	// Logical Destination
 | 
				
			||||||
  LAPIC_DFR = 0x00E0,	/* Destination Format */
 | 
					  LAPIC_DFR = 0x00E0,	// Destination Format
 | 
				
			||||||
  LAPIC_SVR = 0x00F0,	/* Spurious Interrupt Vector */
 | 
					  LAPIC_SVR = 0x00F0,	// Spurious Interrupt Vector
 | 
				
			||||||
  LAPIC_ISR = 0x0100,	/* Interrupt Status (8 registers) */
 | 
					  LAPIC_ISR = 0x0100,	// Interrupt Status (8 registers)
 | 
				
			||||||
  LAPIC_TMR = 0x0180,	/* Trigger Mode (8 registers) */
 | 
					  LAPIC_TMR = 0x0180,	// Trigger Mode (8 registers)
 | 
				
			||||||
  LAPIC_IRR = 0x0200,	/* Interrupt Request (8 registers) */
 | 
					  LAPIC_IRR = 0x0200,	// Interrupt Request (8 registers)
 | 
				
			||||||
  LAPIC_ESR = 0x0280,	/* Error Status */
 | 
					  LAPIC_ESR = 0x0280,	// Error Status
 | 
				
			||||||
  LAPIC_ICRLO = 0x0300,	/* Interrupt Command */
 | 
					  LAPIC_ICRLO = 0x0300,	// Interrupt Command
 | 
				
			||||||
  LAPIC_ICRHI = 0x0310,	/* Interrupt Command [63:32] */
 | 
					  LAPIC_ICRHI = 0x0310,	// Interrupt Command [63:32]
 | 
				
			||||||
  LAPIC_TIMER = 0x0320,	/* Local Vector Table 0 (TIMER) */
 | 
					  LAPIC_TIMER = 0x0320,	// Local Vector Table 0 (TIMER)
 | 
				
			||||||
  LAPIC_PCINT = 0x0340,	/* Performance Counter LVT */
 | 
					  LAPIC_PCINT = 0x0340,	// Performance Counter LVT
 | 
				
			||||||
  LAPIC_LINT0 = 0x0350,	/* Local Vector Table 1 (LINT0) */
 | 
					  LAPIC_LINT0 = 0x0350,	// Local Vector Table 1 (LINT0)
 | 
				
			||||||
  LAPIC_LINT1 = 0x0360,	/* Local Vector Table 2 (LINT1) */
 | 
					  LAPIC_LINT1 = 0x0360,	// Local Vector Table 2 (LINT1)
 | 
				
			||||||
  LAPIC_ERROR = 0x0370,	/* Local Vector Table 3 (ERROR) */
 | 
					  LAPIC_ERROR = 0x0370,	// Local Vector Table 3 (ERROR)
 | 
				
			||||||
  LAPIC_TICR = 0x0380,	/* Timer Initial Count */
 | 
					  LAPIC_TICR = 0x0380,	// Timer Initial Count
 | 
				
			||||||
  LAPIC_TCCR = 0x0390,	/* Timer Current Count */
 | 
					  LAPIC_TCCR = 0x0390,	// Timer Current Count
 | 
				
			||||||
  LAPIC_TDCR = 0x03E0,	/* Timer Divide Configuration */
 | 
					  LAPIC_TDCR = 0x03E0,	// Timer Divide Configuration
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {					/* LAPIC_SVR */
 | 
					enum {					// LAPIC_SVR
 | 
				
			||||||
  LAPIC_ENABLE	= 0x00000100,	/* Unit Enable */
 | 
					  LAPIC_ENABLE	= 0x00000100,	// Unit Enable
 | 
				
			||||||
  LAPIC_FOCUS	= 0x00000200,	/* Focus Processor Checking Disable */
 | 
					  LAPIC_FOCUS	= 0x00000200,	// Focus Processor Checking Disable
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {					/* LAPIC_ICRLO */
 | 
					enum {					// LAPIC_ICRLO
 | 
				
			||||||
					/* [14] IPI Trigger Mode Level (RW) */
 | 
										// [14] IPI Trigger Mode Level (RW)
 | 
				
			||||||
  LAPIC_DEASSERT = 0x00000000,	/* Deassert level-sensitive interrupt */
 | 
					  LAPIC_DEASSERT = 0x00000000,	// Deassert level-sensitive interrupt
 | 
				
			||||||
  LAPIC_ASSERT	= 0x00004000,	/* Assert level-sensitive interrupt */
 | 
					  LAPIC_ASSERT	= 0x00004000,	// Assert level-sensitive interrupt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* [17:16] Remote Read Status */
 | 
					  // [17:16] Remote Read Status
 | 
				
			||||||
  LAPIC_INVALID	= 0x00000000,	/* Invalid */
 | 
					  LAPIC_INVALID	= 0x00000000,	// Invalid
 | 
				
			||||||
  LAPIC_WAIT	= 0x00010000,	/* In-Progress */
 | 
					  LAPIC_WAIT	= 0x00010000,	// In-Progress
 | 
				
			||||||
  LAPIC_VALID	= 0x00020000,	/* Valid */
 | 
					  LAPIC_VALID	= 0x00020000,	// Valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* [19:18] Destination Shorthand */
 | 
					  // [19:18] Destination Shorthand
 | 
				
			||||||
  LAPIC_FIELD	= 0x00000000,	/* No shorthand */
 | 
					  LAPIC_FIELD	= 0x00000000,	// No shorthand
 | 
				
			||||||
  LAPIC_SELF	= 0x00040000,	/* Self is single destination */
 | 
					  LAPIC_SELF	= 0x00040000,	// Self is single destination
 | 
				
			||||||
  LAPIC_ALLINC	= 0x00080000,	/* All including self */
 | 
					  LAPIC_ALLINC	= 0x00080000,	// All including self
 | 
				
			||||||
  LAPIC_ALLEXC	= 0x000C0000,	/* All Excluding self */
 | 
					  LAPIC_ALLEXC	= 0x000C0000,	// All Excluding self
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {					/* LAPIC_ESR */
 | 
					enum {					// LAPIC_ESR
 | 
				
			||||||
  LAPIC_SENDCS	= 0x00000001,	/* Send CS Error */
 | 
					  LAPIC_SENDCS	= 0x00000001,	// Send CS Error
 | 
				
			||||||
  LAPIC_RCVCS	= 0x00000002,	/* Receive CS Error */
 | 
					  LAPIC_RCVCS	= 0x00000002,	// Receive CS Error
 | 
				
			||||||
  LAPIC_SENDACCEPT = 0x00000004,	/* Send Accept Error */
 | 
					  LAPIC_SENDACCEPT = 0x00000004,	// Send Accept Error
 | 
				
			||||||
  LAPIC_RCVACCEPT = 0x00000008,	/* Receive Accept Error */
 | 
					  LAPIC_RCVACCEPT = 0x00000008,	// Receive Accept Error
 | 
				
			||||||
  LAPIC_SENDVECTOR = 0x00000020,	/* Send Illegal Vector */
 | 
					  LAPIC_SENDVECTOR = 0x00000020,	// Send Illegal Vector
 | 
				
			||||||
  LAPIC_RCVVECTOR = 0x00000040,	/* Receive Illegal Vector */
 | 
					  LAPIC_RCVVECTOR = 0x00000040,	// Receive Illegal Vector
 | 
				
			||||||
  LAPIC_REGISTER = 0x00000080,	/* Illegal Register Address */
 | 
					  LAPIC_REGISTER = 0x00000080,	// Illegal Register Address
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {					/* LAPIC_TIMER */
 | 
					enum {					// LAPIC_TIMER
 | 
				
			||||||
					/* [17] Timer Mode (RW) */
 | 
										// [17] Timer Mode (RW)
 | 
				
			||||||
  LAPIC_ONESHOT	= 0x00000000,	/* One-shot */
 | 
					  LAPIC_ONESHOT	= 0x00000000,	// One-shot
 | 
				
			||||||
  LAPIC_PERIODIC = 0x00020000,	/* Periodic */
 | 
					  LAPIC_PERIODIC = 0x00020000,	// Periodic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* [19:18] Timer Base (RW) */
 | 
					  // [19:18] Timer Base (RW)
 | 
				
			||||||
  LAPIC_CLKIN	= 0x00000000,	/* use CLKIN as input */
 | 
					  LAPIC_CLKIN	= 0x00000000,	// use CLKIN as input
 | 
				
			||||||
  LAPIC_TMBASE	= 0x00040000,	/* use TMBASE */
 | 
					  LAPIC_TMBASE	= 0x00040000,	// use TMBASE
 | 
				
			||||||
  LAPIC_DIVIDER	= 0x00080000,	/* use output of the divider */
 | 
					  LAPIC_DIVIDER	= 0x00080000,	// use output of the divider
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {					/* LAPIC_TDCR */
 | 
					enum {					// LAPIC_TDCR
 | 
				
			||||||
  LAPIC_X2 = 0x00000000,	/* divide by 2 */
 | 
					  LAPIC_X2 = 0x00000000,	// divide by 2
 | 
				
			||||||
  LAPIC_X4 = 0x00000001,	/* divide by 4 */
 | 
					  LAPIC_X4 = 0x00000001,	// divide by 4
 | 
				
			||||||
  LAPIC_X8 = 0x00000002,	/* divide by 8 */
 | 
					  LAPIC_X8 = 0x00000002,	// divide by 8
 | 
				
			||||||
  LAPIC_X16 = 0x00000003,	/* divide by 16 */
 | 
					  LAPIC_X16 = 0x00000003,	// divide by 16
 | 
				
			||||||
  LAPIC_X32 = 0x00000008,	/* divide by 32 */
 | 
					  LAPIC_X32 = 0x00000008,	// divide by 32
 | 
				
			||||||
  LAPIC_X64 = 0x00000009,	/* divide by 64 */
 | 
					  LAPIC_X64 = 0x00000009,	// divide by 64
 | 
				
			||||||
  LAPIC_X128 = 0x0000000A,	/* divide by 128 */
 | 
					  LAPIC_X128 = 0x0000000A,	// divide by 128
 | 
				
			||||||
  LAPIC_X1 = 0x0000000B,	/* divide by 1 */
 | 
					  LAPIC_X1 = 0x0000000B,	// divide by 1
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint *lapicaddr;
 | 
					uint *lapicaddr;
 | 
				
			||||||
| 
						 | 
					@ -128,7 +128,7 @@ lapic_init(int c)
 | 
				
			||||||
  lapic_write(LAPIC_TPR, 0xFF);  // no interrupts for now
 | 
					  lapic_write(LAPIC_TPR, 0xFF);  // no interrupts for now
 | 
				
			||||||
  lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));  // enable APIC
 | 
					  lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));  // enable APIC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // in virtual wire mode, set up the LINT0 and LINT1 as follows:
 | 
					  // In virtual wire mode, set up the LINT0 and LINT1 as follows:
 | 
				
			||||||
  lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT);
 | 
					  lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT);
 | 
				
			||||||
  lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI);
 | 
					  lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,9 +141,7 @@ lapic_init(int c)
 | 
				
			||||||
  lapic_write(LAPIC_ESR, 0);
 | 
					  lapic_write(LAPIC_ESR, 0);
 | 
				
			||||||
  lapic_read(LAPIC_ESR);
 | 
					  lapic_read(LAPIC_ESR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  // Issue an INIT Level De-Assert to synchronise arbitration ID's.
 | 
				
			||||||
   * Issue an INIT Level De-Assert to synchronise arbitration ID's.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  lapic_write(LAPIC_ICRHI, 0);
 | 
					  lapic_write(LAPIC_ICRHI, 0);
 | 
				
			||||||
  lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
 | 
					  lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT);
 | 
				
			||||||
  while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
 | 
					  while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								mmu.h
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								mmu.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,6 +1,4 @@
 | 
				
			||||||
/*
 | 
					// This file contains definitions for the x86 memory management unit (MMU).
 | 
				
			||||||
 * This file contains definitions for the x86 memory management unit (MMU).
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Eflags register
 | 
					// Eflags register
 | 
				
			||||||
#define FL_CF           0x00000001      // Carry Flag
 | 
					#define FL_CF           0x00000001      // Carry Flag
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										44
									
								
								mp.c
									
										
									
									
									
								
							
							
						
						
									
										44
									
								
								mp.c
									
										
									
									
									
								
							| 
						 | 
					@ -55,6 +55,11 @@ mp_scan(uchar *addr, int len)
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Search for the MP Floating Pointer Structure, which according to the
 | 
				
			||||||
 | 
					// spec is in one of the following three locations:
 | 
				
			||||||
 | 
					// 1) in the first KB of the EBDA;
 | 
				
			||||||
 | 
					// 2) in the last KB of system base memory;
 | 
				
			||||||
 | 
					// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
 | 
				
			||||||
static struct mp*
 | 
					static struct mp*
 | 
				
			||||||
mp_search(void)
 | 
					mp_search(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -62,13 +67,6 @@ mp_search(void)
 | 
				
			||||||
  uint p;
 | 
					  uint p;
 | 
				
			||||||
  struct mp *mp;
 | 
					  struct mp *mp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
   * Search for the MP Floating Pointer Structure, which according to the
 | 
					 | 
				
			||||||
   * spec is in one of the following three locations:
 | 
					 | 
				
			||||||
   * 1) in the first KB of the EBDA;
 | 
					 | 
				
			||||||
   * 2) in the last KB of system base memory;
 | 
					 | 
				
			||||||
   * 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  bda = (uchar*) 0x400;
 | 
					  bda = (uchar*) 0x400;
 | 
				
			||||||
  if((p = (bda[0x0F]<<8)|bda[0x0E])){
 | 
					  if((p = (bda[0x0F]<<8)|bda[0x0E])){
 | 
				
			||||||
    if((mp = mp_scan((uchar*) p, 1024)))
 | 
					    if((mp = mp_scan((uchar*) p, 1024)))
 | 
				
			||||||
| 
						 | 
					@ -82,6 +80,11 @@ mp_search(void)
 | 
				
			||||||
  return mp_scan((uchar*)0xF0000, 0x10000);
 | 
					  return mp_scan((uchar*)0xF0000, 0x10000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Search for an MP configuration table. For now,
 | 
				
			||||||
 | 
					// don't accept the default configurations (physaddr == 0).
 | 
				
			||||||
 | 
					// Check for correct signature, calculate the checksum and,
 | 
				
			||||||
 | 
					// if correct, check the version.
 | 
				
			||||||
 | 
					// To do: check extended table checksum.
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
mp_detect(void)
 | 
					mp_detect(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -89,13 +92,6 @@ mp_detect(void)
 | 
				
			||||||
  uchar *p, sum;
 | 
					  uchar *p, sum;
 | 
				
			||||||
  uint length;
 | 
					  uint length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
   * Search for an MP configuration table. For now,
 | 
					 | 
				
			||||||
   * don't accept the default configurations (physaddr == 0).
 | 
					 | 
				
			||||||
   * Check for correct signature, calculate the checksum and,
 | 
					 | 
				
			||||||
   * if correct, check the version.
 | 
					 | 
				
			||||||
   * To do: check extended table checksum.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  if((mp = mp_search()) == 0 || mp->physaddr == 0)
 | 
					  if((mp = mp_search()) == 0 || mp->physaddr == 0)
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,13 +124,13 @@ mp_init(void)
 | 
				
			||||||
  uchar byte;
 | 
					  uchar byte;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ncpu = 0;
 | 
					  ncpu = 0;
 | 
				
			||||||
  if((r = mp_detect()) != 0) return;
 | 
					  if((r = mp_detect()) != 0)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Run through the table saving information needed for starting
 | 
				
			||||||
 | 
					  // application processors and initialising any I/O APICs. The table
 | 
				
			||||||
 | 
					  // is guaranteed to be in order such that only one pass is necessary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
   * Run through the table saving information needed for starting
 | 
					 | 
				
			||||||
   * application processors and initialising any I/O APICs. The table
 | 
					 | 
				
			||||||
   * is guaranteed to be in order such that only one pass is necessary.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  mpctb = (struct mpctb*) mp->physaddr;
 | 
					  mpctb = (struct mpctb*) mp->physaddr;
 | 
				
			||||||
  lapicaddr = (uint*) mpctb->lapicaddr;
 | 
					  lapicaddr = (uint*) mpctb->lapicaddr;
 | 
				
			||||||
  p = ((uchar*)mpctb)+sizeof(struct mpctb);
 | 
					  p = ((uchar*)mpctb)+sizeof(struct mpctb);
 | 
				
			||||||
| 
						 | 
					@ -179,10 +175,10 @@ mp_init(void)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(mp->imcrp) {  // it appears that bochs doesn't support IMCR, and code won't run
 | 
					  if(mp->imcrp) {  // it appears that bochs doesn't support IMCR, and code won't run
 | 
				
			||||||
    outb(0x22, 0x70);   /* select IMCR */
 | 
					    outb(0x22, 0x70);   // select IMCR
 | 
				
			||||||
    byte = inb(0x23);   /* current contents */
 | 
					    byte = inb(0x23);   // current contents
 | 
				
			||||||
    byte |= 0x01;       /* mask external INTR */
 | 
					    byte |= 0x01;       // mask external INTR
 | 
				
			||||||
    outb(0x23, byte);   /* disconnect 8259s/NMI */
 | 
					    outb(0x23, byte);   // disconnect 8259s/NMI
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										171
									
								
								mp.h
									
										
									
									
									
								
							
							
						
						
									
										171
									
								
								mp.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,123 +1,118 @@
 | 
				
			||||||
/*
 | 
					// See MultiProcessor Specification Version 1.[14].
 | 
				
			||||||
 * See MultiProcessor Specification Version 1.[14].
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mp {             /* floating pointer */
 | 
					struct mp {             // floating pointer
 | 
				
			||||||
  uchar signature[4];           /* "_MP_" */
 | 
					  uchar signature[4];           // "_MP_"
 | 
				
			||||||
  void *physaddr;               /* physical address of MP configuration table */
 | 
					  void *physaddr;               // physical address of MP configuration table
 | 
				
			||||||
  uchar length;                 /* 1 */
 | 
					  uchar length;                 // 1
 | 
				
			||||||
  uchar specrev;                /* [14] */
 | 
					  uchar specrev;                // [14]
 | 
				
			||||||
  uchar checksum;               /* all bytes must add up to 0 */
 | 
					  uchar checksum;               // all bytes must add up to 0
 | 
				
			||||||
  uchar type;                   /* MP system configuration type */
 | 
					  uchar type;                   // MP system configuration type
 | 
				
			||||||
  uchar imcrp;
 | 
					  uchar imcrp;
 | 
				
			||||||
  uchar reserved[3];
 | 
					  uchar reserved[3];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mpctb {          /* configuration table header */
 | 
					struct mpctb {          // configuration table header
 | 
				
			||||||
  uchar signature[4];           /* "PCMP" */
 | 
					  uchar signature[4];           // "PCMP"
 | 
				
			||||||
  ushort length;                /* total table length */
 | 
					  ushort length;                // total table length
 | 
				
			||||||
  uchar version;                /* [14] */
 | 
					  uchar version;                // [14]
 | 
				
			||||||
  uchar checksum;               /* all bytes must add up to 0 */
 | 
					  uchar checksum;               // all bytes must add up to 0
 | 
				
			||||||
  uchar product[20];            /* product id */
 | 
					  uchar product[20];            // product id
 | 
				
			||||||
  uint *oemtable;              /* OEM table pointer */
 | 
					  uint *oemtable;              // OEM table pointer
 | 
				
			||||||
  ushort oemlength;             /* OEM table length */
 | 
					  ushort oemlength;             // OEM table length
 | 
				
			||||||
  ushort entry;                 /* entry count */
 | 
					  ushort entry;                 // entry count
 | 
				
			||||||
  uint *lapicaddr;             /* address of local APIC */
 | 
					  uint *lapicaddr;             // address of local APIC
 | 
				
			||||||
  ushort xlength;               /* extended table length */
 | 
					  ushort xlength;               // extended table length
 | 
				
			||||||
  uchar xchecksum;              /* extended table checksum */
 | 
					  uchar xchecksum;              // extended table checksum
 | 
				
			||||||
  uchar reserved;
 | 
					  uchar reserved;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mppe {           /* processor table entry */
 | 
					struct mppe {           // processor table entry
 | 
				
			||||||
  uchar type;                   /* entry type (0) */
 | 
					  uchar type;                   // entry type (0)
 | 
				
			||||||
  uchar apicid;                 /* local APIC id */
 | 
					  uchar apicid;                 // local APIC id
 | 
				
			||||||
  uchar version;                /* local APIC verison */
 | 
					  uchar version;                // local APIC verison
 | 
				
			||||||
  uchar flags;                  /* CPU flags */
 | 
					  uchar flags;                  // CPU flags
 | 
				
			||||||
  uchar signature[4];           /* CPU signature */
 | 
					  uchar signature[4];           // CPU signature
 | 
				
			||||||
  uint feature;                 /* feature flags from CPUID instruction */
 | 
					  uint feature;                 // feature flags from CPUID instruction
 | 
				
			||||||
  uchar reserved[8];
 | 
					  uchar reserved[8];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mpbe {           /* bus table entry */
 | 
					struct mpbe {           // bus table entry
 | 
				
			||||||
  uchar type;                   /* entry type (1) */
 | 
					  uchar type;                   // entry type (1)
 | 
				
			||||||
  uchar busno;                  /* bus id */
 | 
					  uchar busno;                  // bus id
 | 
				
			||||||
  char string[6];               /* bus type string */
 | 
					  char string[6];               // bus type string
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mpioapic {       /* I/O APIC table entry */
 | 
					struct mpioapic {       // I/O APIC table entry
 | 
				
			||||||
  uchar type;                   /* entry type (2) */
 | 
					  uchar type;                   // entry type (2)
 | 
				
			||||||
  uchar apicno;                 /* I/O APIC id */
 | 
					  uchar apicno;                 // I/O APIC id
 | 
				
			||||||
  uchar version;                /* I/O APIC version */
 | 
					  uchar version;                // I/O APIC version
 | 
				
			||||||
  uchar flags;                  /* I/O APIC flags */
 | 
					  uchar flags;                  // I/O APIC flags
 | 
				
			||||||
  uint *addr;                  /* I/O APIC address */
 | 
					  uint *addr;                  // I/O APIC address
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mpie {           /* interrupt table entry */
 | 
					struct mpie {           // interrupt table entry
 | 
				
			||||||
  uchar type;                   /* entry type ([34]) */
 | 
					  uchar type;                   // entry type ([34])
 | 
				
			||||||
  uchar intr;                   /* interrupt type */
 | 
					  uchar intr;                   // interrupt type
 | 
				
			||||||
  ushort flags;                 /* interrupt flag */
 | 
					  ushort flags;                 // interrupt flag
 | 
				
			||||||
  uchar busno;                  /* source bus id */
 | 
					  uchar busno;                  // source bus id
 | 
				
			||||||
  uchar irq;                    /* source bus irq */
 | 
					  uchar irq;                    // source bus irq
 | 
				
			||||||
  uchar apicno;                 /* destination APIC id */
 | 
					  uchar apicno;                 // destination APIC id
 | 
				
			||||||
  uchar intin;                  /* destination APIC [L]INTIN# */
 | 
					  uchar intin;                  // destination APIC [L]INTIN#
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {                  /* table entry types */
 | 
					enum {                  // table entry types
 | 
				
			||||||
  MPPROCESSOR   = 0x00,         /* one entry per processor */
 | 
					  MPPROCESSOR   = 0x00,         // one entry per processor
 | 
				
			||||||
  MPBUS = 0x01,                 /* one entry per bus */
 | 
					  MPBUS = 0x01,                 // one entry per bus
 | 
				
			||||||
  MPIOAPIC = 0x02,              /* one entry per I/O APIC */
 | 
					  MPIOAPIC = 0x02,              // one entry per I/O APIC
 | 
				
			||||||
  MPIOINTR = 0x03,              /* one entry per bus interrupt source */
 | 
					  MPIOINTR = 0x03,              // one entry per bus interrupt source
 | 
				
			||||||
  MPLINTR = 0x04,               /* one entry per system interrupt source */
 | 
					  MPLINTR = 0x04,               // one entry per system interrupt source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MPSASM = 0x80,
 | 
					  MPSASM = 0x80,
 | 
				
			||||||
  MPHIERARCHY   = 0x81,
 | 
					  MPHIERARCHY   = 0x81,
 | 
				
			||||||
  MPCBASM = 0x82,
 | 
					  MPCBASM = 0x82,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        /* PCMPprocessor and PCMPioapic flags */
 | 
					                        // PCMPprocessor and PCMPioapic flags
 | 
				
			||||||
  MPEN = 0x01,                  /* enabled */
 | 
					  MPEN = 0x01,                  // enabled
 | 
				
			||||||
  MPBP = 0x02,                  /* bootstrap processor */
 | 
					  MPBP = 0x02,                  // bootstrap processor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        /* PCMPiointr and PCMPlintr flags */
 | 
					                        // PCMPiointr and PCMPlintr flags
 | 
				
			||||||
  MPPOMASK = 0x03,              /* polarity conforms to specifications of bus */
 | 
					  MPPOMASK = 0x03,              // polarity conforms to specifications of bus
 | 
				
			||||||
  MPHIGH = 0x01,                /* active high */
 | 
					  MPHIGH = 0x01,                // active high
 | 
				
			||||||
  MPLOW = 0x03,                 /* active low */
 | 
					  MPLOW = 0x03,                 // active low
 | 
				
			||||||
  MPELMASK = 0x0C,              /* trigger mode of APIC input signals */
 | 
					  MPELMASK = 0x0C,              // trigger mode of APIC input signals
 | 
				
			||||||
  MPEDGE = 0x04,                /* edge-triggered */
 | 
					  MPEDGE = 0x04,                // edge-triggered
 | 
				
			||||||
  MPLEVEL = 0x0C,               /* level-triggered */
 | 
					  MPLEVEL = 0x0C,               // level-triggered
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        /* PCMPiointr and PCMPlintr interrupt type */
 | 
					                        // PCMPiointr and PCMPlintr interrupt type
 | 
				
			||||||
  MPINT = 0x00,                 /* vectored interrupt from APIC Rdt */
 | 
					  MPINT = 0x00,                 // vectored interrupt from APIC Rdt
 | 
				
			||||||
  MPNMI = 0x01,                 /* non-maskable interrupt */
 | 
					  MPNMI = 0x01,                 // non-maskable interrupt
 | 
				
			||||||
  MPSMI = 0x02,                 /* system management interrupt */
 | 
					  MPSMI = 0x02,                 // system management interrupt
 | 
				
			||||||
  MPExtINT = 0x03,              /* vectored interrupt from external PIC */
 | 
					  MPExtINT = 0x03,              // vectored interrupt from external PIC
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Common bits for
 | 
				
			||||||
 * Common bits for
 | 
					//      I/O APIC Redirection Table Entry;
 | 
				
			||||||
 *      I/O APIC Redirection Table Entry;
 | 
					//      Local APIC Local Interrupt Vector Table;
 | 
				
			||||||
 *      Local APIC Local Interrupt Vector Table;
 | 
					//      Local APIC Inter-Processor Interrupt;
 | 
				
			||||||
 *      Local APIC Inter-Processor Interrupt;
 | 
					//      Local APIC Timer Vector Table.
 | 
				
			||||||
 *      Local APIC Timer Vector Table.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
  APIC_FIXED     = 0x00000000,  /* [10:8] Delivery Mode */
 | 
					  APIC_FIXED     = 0x00000000,  // [10:8] Delivery Mode
 | 
				
			||||||
  APIC_LOWEST    = 0x00000100,  /* Lowest priority */
 | 
					  APIC_LOWEST    = 0x00000100,  // Lowest priority
 | 
				
			||||||
  APIC_SMI       = 0x00000200,  /* System Management Interrupt */
 | 
					  APIC_SMI       = 0x00000200,  // System Management Interrupt
 | 
				
			||||||
  APIC_RR        = 0x00000300,  /* Remote Read */
 | 
					  APIC_RR        = 0x00000300,  // Remote Read
 | 
				
			||||||
  APIC_NMI       = 0x00000400,
 | 
					  APIC_NMI       = 0x00000400,
 | 
				
			||||||
  APIC_INIT      = 0x00000500,  /* INIT/RESET */
 | 
					  APIC_INIT      = 0x00000500,  // INIT/RESET
 | 
				
			||||||
  APIC_STARTUP   = 0x00000600,  /* Startup IPI */
 | 
					  APIC_STARTUP   = 0x00000600,  // Startup IPI
 | 
				
			||||||
  APIC_EXTINT    = 0x00000700,
 | 
					  APIC_EXTINT    = 0x00000700,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  APIC_PHYSICAL  = 0x00000000,  /* [11] Destination Mode (RW) */
 | 
					  APIC_PHYSICAL  = 0x00000000,  // [11] Destination Mode (RW)
 | 
				
			||||||
  APIC_LOGICAL   = 0x00000800,
 | 
					  APIC_LOGICAL   = 0x00000800,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  APIC_DELIVS    = 0x00001000,  /* [12] Delivery Status (RO) */
 | 
					  APIC_DELIVS    = 0x00001000,  // [12] Delivery Status (RO)
 | 
				
			||||||
  APIC_HIGH      = 0x00000000,  /* [13] Interrupt Input Pin Polarity (RW) */
 | 
					  APIC_HIGH      = 0x00000000,  // [13] Interrupt Input Pin Polarity (RW)
 | 
				
			||||||
  APIC_LOW       = 0x00002000,
 | 
					  APIC_LOW       = 0x00002000,
 | 
				
			||||||
  APIC_REMOTEIRR = 0x00004000,  /* [14] Remote IRR (RO) */
 | 
					  APIC_REMOTEIRR = 0x00004000,  // [14] Remote IRR (RO)
 | 
				
			||||||
  APIC_EDGE      = 0x00000000,  /* [15] Trigger Mode (RW) */
 | 
					  APIC_EDGE      = 0x00000000,  // [15] Trigger Mode (RW)
 | 
				
			||||||
  APIC_LEVEL     = 0x00008000,
 | 
					  APIC_LEVEL     = 0x00008000,
 | 
				
			||||||
  APIC_IMASK     = 0x00010000,  /* [16] Interrupt Mask */
 | 
					  APIC_IMASK     = 0x00010000,  // [16] Interrupt Mask
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								picirq.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								picirq.c
									
										
									
									
									
								
							| 
						 | 
					@ -22,7 +22,7 @@ irq_setmask_8259A(ushort mask)
 | 
				
			||||||
  outb(IO_PIC2+1, (char)(mask >> 8));
 | 
					  outb(IO_PIC2+1, (char)(mask >> 8));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Initialize the 8259A interrupt controllers. */
 | 
					// Initialize the 8259A interrupt controllers.
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
pic_init(void)
 | 
					pic_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -67,11 +67,11 @@ pic_init(void)
 | 
				
			||||||
  //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
 | 
					  //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
 | 
				
			||||||
  //    p:  0 = no polling, 1 = polling mode
 | 
					  //    p:  0 = no polling, 1 = polling mode
 | 
				
			||||||
  //   rs:  0x = NOP, 10 = read IRR, 11 = read ISR
 | 
					  //   rs:  0x = NOP, 10 = read IRR, 11 = read ISR
 | 
				
			||||||
  outb(IO_PIC1, 0x68);             /* clear specific mask */
 | 
					  outb(IO_PIC1, 0x68);             // clear specific mask
 | 
				
			||||||
  outb(IO_PIC1, 0x0a);             /* read IRR by default */
 | 
					  outb(IO_PIC1, 0x0a);             // read IRR by default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  outb(IO_PIC2, 0x68);               /* OCW3 */
 | 
					  outb(IO_PIC2, 0x68);             // OCW3
 | 
				
			||||||
  outb(IO_PIC2, 0x0a);               /* OCW3 */
 | 
					  outb(IO_PIC2, 0x0a);             // OCW3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(irq_mask_8259A != 0xFFFF)
 | 
					  if(irq_mask_8259A != 0xFFFF)
 | 
				
			||||||
    irq_setmask_8259A(irq_mask_8259A);
 | 
					    irq_setmask_8259A(irq_mask_8259A);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								printf.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								printf.c
									
										
									
									
									
								
							| 
						 | 
					@ -33,9 +33,7 @@ printint(int fd, int xx, int base, int sgn)
 | 
				
			||||||
    putc(fd, buf[i]);
 | 
					    putc(fd, buf[i]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Print to the given fd. Only understands %d, %x, %p, %s.
 | 
				
			||||||
 * printf to the stdout. only understands %d, %x, %p, %s.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
printf(int fd, char *fmt, ...)
 | 
					printf(int fd, char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
					@ -21,11 +21,10 @@ pinit(void)
 | 
				
			||||||
  initlock(&proc_table_lock, "proc_table");
 | 
					  initlock(&proc_table_lock, "proc_table");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Set up CPU's segment descriptors and task state for a
 | 
				
			||||||
 * set up CPU's segment descriptors and task state for a
 | 
					// given process.
 | 
				
			||||||
 * given process. If p==0, set up for "idle" state for
 | 
					// If p==0, set up for "idle" state for when scheduler()
 | 
				
			||||||
 * when scheduler() isn't running any process.
 | 
					// is idling, not running any process.
 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
setupsegs(struct proc *p)
 | 
					setupsegs(struct proc *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								proc.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,20 +1,10 @@
 | 
				
			||||||
/*
 | 
					// segments in proc->gdt
 | 
				
			||||||
 * p->mem:
 | 
					 | 
				
			||||||
 *   text
 | 
					 | 
				
			||||||
 *   original data and bss
 | 
					 | 
				
			||||||
 *   fixed-size stack
 | 
					 | 
				
			||||||
 *   expandable heap
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * segments in proc->gdt
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define SEG_KCODE 1 // kernel code
 | 
					#define SEG_KCODE 1 // kernel code
 | 
				
			||||||
#define SEG_KDATA 2 // kernel data+stack
 | 
					#define SEG_KDATA 2 // kernel data+stack
 | 
				
			||||||
#define SEG_UCODE 3
 | 
					#define SEG_UCODE 3
 | 
				
			||||||
#define SEG_UDATA 4
 | 
					#define SEG_UDATA 4
 | 
				
			||||||
#define SEG_TSS 5   // this process's task state
 | 
					#define SEG_TSS   5   // this process's task state
 | 
				
			||||||
#define NSEGS 6
 | 
					#define NSEGS     6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct jmpbuf {
 | 
					struct jmpbuf {
 | 
				
			||||||
  // saved registers for kernel context switches
 | 
					  // saved registers for kernel context switches
 | 
				
			||||||
| 
						 | 
					@ -37,6 +27,11 @@ enum proc_state { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct proc{
 | 
					struct proc{
 | 
				
			||||||
  char *mem;    // start of process's memory (a kernel address)
 | 
					  char *mem;    // start of process's memory (a kernel address)
 | 
				
			||||||
 | 
					    // process memory is laid out contiguously:
 | 
				
			||||||
 | 
					    //   text
 | 
				
			||||||
 | 
					    //   original data and bss
 | 
				
			||||||
 | 
					    //   fixed-size stack
 | 
				
			||||||
 | 
					    //   expandable heap
 | 
				
			||||||
  uint sz;      // user memory size
 | 
					  uint sz;      // user memory size
 | 
				
			||||||
  char *kstack; // kernel stack
 | 
					  char *kstack; // kernel stack
 | 
				
			||||||
  enum proc_state state;
 | 
					  enum proc_state state;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								syscall.c
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								syscall.c
									
										
									
									
									
								
							| 
						 | 
					@ -15,18 +15,14 @@
 | 
				
			||||||
#include "fd.h"
 | 
					#include "fd.h"
 | 
				
			||||||
#include "fcntl.h"
 | 
					#include "fcntl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// User code makes a system call with INT T_SYSCALL.
 | 
				
			||||||
 * User code makes a system call with INT T_SYSCALL.
 | 
					// System call number in %eax.
 | 
				
			||||||
 * System call number in %eax.
 | 
					// Arguments on the stack, from the user call to the C
 | 
				
			||||||
 * Arguments on the stack, from the user call to the C
 | 
					// library system call function. The saved user %esp points
 | 
				
			||||||
 * library system call function. The saved user %esp points
 | 
					// to a saved program counter, and then the first argument.
 | 
				
			||||||
 * to a saved program counter, and then the first argument.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					// Fetch 32 bits from a user-supplied pointer.
 | 
				
			||||||
 * fetch 32 bits from a user-supplied pointer.
 | 
					// Returns 0 if addr was OK, -1 if illegal.
 | 
				
			||||||
 * returns 0 if addr was OK, -1 if illegal.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
fetchint(struct proc *p, uint addr, int *ip)
 | 
					fetchint(struct proc *p, uint addr, int *ip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -58,8 +54,8 @@ fetcharg(int argno, void *ip)
 | 
				
			||||||
  return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);
 | 
					  return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// check that an entire string is valid in user space.
 | 
					// Check that an entire string is valid in user space.
 | 
				
			||||||
// returns the length, not including null, or -1.
 | 
					// Returns the length, not including null, or -1.
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
checkstring(uint s)
 | 
					checkstring(uint s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								trap.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								trap.c
									
										
									
									
									
								
							| 
						 | 
					@ -8,7 +8,7 @@
 | 
				
			||||||
#include "syscall.h"
 | 
					#include "syscall.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gatedesc idt[256];
 | 
					struct gatedesc idt[256];
 | 
				
			||||||
extern uint vectors[]; /* vectors.S, array of 256 entry point addresses */
 | 
					extern uint vectors[];  // in vectors.S: array of 256 entry point addresses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void trapenter(void);
 | 
					extern void trapenter(void);
 | 
				
			||||||
extern void trapenter1(void);
 | 
					extern void trapenter1(void);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								traps.h
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								traps.h
									
										
									
									
									
								
							| 
						 | 
					@ -8,13 +8,13 @@
 | 
				
			||||||
#define T_ILLOP          6          // illegal opcode
 | 
					#define T_ILLOP          6          // illegal opcode
 | 
				
			||||||
#define T_DEVICE         7          // device not available
 | 
					#define T_DEVICE         7          // device not available
 | 
				
			||||||
#define T_DBLFLT         8          // double fault
 | 
					#define T_DBLFLT         8          // double fault
 | 
				
			||||||
/* #define T_COPROC      9 */       // reserved (not generated by recent processors)
 | 
					// #define T_COPROC      9          // reserved (not generated by recent processors)
 | 
				
			||||||
#define T_TSS           10          // invalid task switch segment
 | 
					#define T_TSS           10          // invalid task switch segment
 | 
				
			||||||
#define T_SEGNP         11          // segment not present
 | 
					#define T_SEGNP         11          // segment not present
 | 
				
			||||||
#define T_STACK         12          // stack exception
 | 
					#define T_STACK         12          // stack exception
 | 
				
			||||||
#define T_GPFLT         13          // genernal protection fault
 | 
					#define T_GPFLT         13          // genernal protection fault
 | 
				
			||||||
#define T_PGFLT         14          // page fault
 | 
					#define T_PGFLT         14          // page fault
 | 
				
			||||||
/* #define T_RES        15 */       // reserved
 | 
					// #define T_RES        15          // reserved
 | 
				
			||||||
#define T_FPERR         16          // floating point error
 | 
					#define T_FPERR         16          // floating point error
 | 
				
			||||||
#define T_ALIGN         17          // aligment check
 | 
					#define T_ALIGN         17          // aligment check
 | 
				
			||||||
#define T_MCHK          18          // machine check
 | 
					#define T_MCHK          18          // machine check
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@
 | 
				
			||||||
#define T_SYSCALL       48          // system call
 | 
					#define T_SYSCALL       48          // system call
 | 
				
			||||||
#define T_DEFAULT      500          // catchall
 | 
					#define T_DEFAULT      500          // catchall
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IRQ_OFFSET      32      // IRQ 0 corresponds to int IRQ_OFFSET
 | 
					#define IRQ_OFFSET      32          // IRQ 0 corresponds to int IRQ_OFFSET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IRQ_KBD          1
 | 
					#define IRQ_KBD          1
 | 
				
			||||||
#define IRQ_IDE         14
 | 
					#define IRQ_IDE         14
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,8 +5,8 @@
 | 
				
			||||||
# since otherwise there's no way for trap() to discover
 | 
					# since otherwise there's no way for trap() to discover
 | 
				
			||||||
# the interrupt number.
 | 
					# the interrupt number.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print "/* generated by vectors.pl */\n";
 | 
					print "# generated by vectors.pl - do not edit\n";
 | 
				
			||||||
print "/* handlers */\n";
 | 
					print "# handlers\n";
 | 
				
			||||||
print ".text\n";
 | 
					print ".text\n";
 | 
				
			||||||
print ".globl alltraps\n";
 | 
					print ".globl alltraps\n";
 | 
				
			||||||
for(my $i = 0; $i < 256; $i++){
 | 
					for(my $i = 0; $i < 256; $i++){
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ for(my $i = 0; $i < 256; $i++){
 | 
				
			||||||
    print "  jmp alltraps\n";
 | 
					    print "  jmp alltraps\n";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print "\n/* vector table */\n";
 | 
					print "\n# vector table\n";
 | 
				
			||||||
print ".data\n";
 | 
					print ".data\n";
 | 
				
			||||||
print ".globl vectors\n";
 | 
					print ".globl vectors\n";
 | 
				
			||||||
print "vectors:\n";
 | 
					print "vectors:\n";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								x86.h
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								x86.h
									
										
									
									
									
								
							| 
						 | 
					@ -125,28 +125,31 @@ sti(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct trapframe {
 | 
					struct trapframe {
 | 
				
			||||||
  /* registers as pushed by pusha */
 | 
					  // registers as pushed by pusha
 | 
				
			||||||
  uint edi;
 | 
					  uint edi;
 | 
				
			||||||
  uint esi;
 | 
					  uint esi;
 | 
				
			||||||
  uint ebp;
 | 
					  uint ebp;
 | 
				
			||||||
  uint oesp;      /* Useless */
 | 
					  uint oesp;      // useless & ignored
 | 
				
			||||||
  uint ebx;
 | 
					  uint ebx;
 | 
				
			||||||
  uint edx;
 | 
					  uint edx;
 | 
				
			||||||
  uint ecx;
 | 
					  uint ecx;
 | 
				
			||||||
  uint eax;
 | 
					  uint eax;
 | 
				
			||||||
  /* rest of trap frame */
 | 
					
 | 
				
			||||||
 | 
					  // rest of trap frame
 | 
				
			||||||
  ushort es;
 | 
					  ushort es;
 | 
				
			||||||
  ushort padding1;
 | 
					  ushort padding1;
 | 
				
			||||||
  ushort ds;
 | 
					  ushort ds;
 | 
				
			||||||
  ushort padding2;
 | 
					  ushort padding2;
 | 
				
			||||||
  uint trapno;
 | 
					  uint trapno;
 | 
				
			||||||
  /* below here defined by x86 hardware */
 | 
					
 | 
				
			||||||
 | 
					  // below here defined by x86 hardware
 | 
				
			||||||
  uint err;
 | 
					  uint err;
 | 
				
			||||||
  uint eip;
 | 
					  uint eip;
 | 
				
			||||||
  ushort cs;
 | 
					  ushort cs;
 | 
				
			||||||
  ushort padding3;
 | 
					  ushort padding3;
 | 
				
			||||||
  uint eflags;
 | 
					  uint eflags;
 | 
				
			||||||
  /* below here only when crossing rings, such as from user to kernel */
 | 
					
 | 
				
			||||||
 | 
					  // below here only when crossing rings, such as from user to kernel
 | 
				
			||||||
  uint esp;
 | 
					  uint esp;
 | 
				
			||||||
  ushort ss;
 | 
					  ushort ss;
 | 
				
			||||||
  ushort padding4;
 | 
					  ushort padding4;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue