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