spacing fixes: no tabs, 2-space indents (for rtm)
This commit is contained in:
		
							parent
							
								
									45854caa93
								
							
						
					
					
						commit
						a650c606fe
					
				
					 33 changed files with 913 additions and 905 deletions
				
			
		
							
								
								
									
										27
									
								
								asm.h
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								asm.h
									
										
									
									
									
								
							|  | @ -2,17 +2,18 @@ | ||||||
| // macros to create x86 segments from assembler
 | // macros to create x86 segments from assembler
 | ||||||
| //
 | //
 | ||||||
| 
 | 
 | ||||||
| #define SEG_NULLASM						\ | #define SEG_NULLASM                                             \ | ||||||
| 	.word 0, 0;						\ |         .word 0, 0;                                             \ | ||||||
| 	.byte 0, 0, 0, 0 |         .byte 0, 0, 0, 0 | ||||||
| #define SEG_ASM(type,base,lim)					\ |  | ||||||
| 	.word (((lim) >> 12) & 0xffff), ((base) & 0xffff);	\ |  | ||||||
| 	.byte (((base) >> 16) & 0xff), (0x90 | (type)),		\ |  | ||||||
| 		(0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) |  | ||||||
| 
 | 
 | ||||||
| #define STA_X		0x8	    // Executable segment
 | #define SEG_ASM(type,base,lim)                                  \ | ||||||
| #define STA_E		0x4	    // Expand down (non-executable segments)
 |         .word (((lim) >> 12) & 0xffff), ((base) & 0xffff);      \ | ||||||
| #define STA_C		0x4	    // Conforming code segment (executable only)
 |         .byte (((base) >> 16) & 0xff), (0x90 | (type)),         \ | ||||||
| #define STA_W		0x2	    // Writeable (non-executable segments)
 |                 (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) | ||||||
| #define STA_R		0x2	    // Readable (executable segments)
 | 
 | ||||||
| #define STA_A		0x1	    // Accessed
 | #define STA_X           0x8         // Executable segment
 | ||||||
|  | #define STA_E           0x4         // Expand down (non-executable segments)
 | ||||||
|  | #define STA_C           0x4         // Conforming code segment (executable only)
 | ||||||
|  | #define STA_W           0x2         // Writeable (non-executable segments)
 | ||||||
|  | #define STA_R           0x2         // Readable (executable segments)
 | ||||||
|  | #define STA_A           0x1         // Accessed
 | ||||||
|  |  | ||||||
							
								
								
									
										139
									
								
								bootasm.S
									
										
									
									
									
								
							
							
						
						
									
										139
									
								
								bootasm.S
									
										
									
									
									
								
							|  | @ -1,36 +1,37 @@ | ||||||
| #include "asm.h" | #include "asm.h" | ||||||
| 	 |          | ||||||
| .set PROT_MODE_CSEG,0x8		# code segment selector | .set PROT_MODE_CSEG,0x8         # code segment selector | ||||||
| .set PROT_MODE_DSEG,0x10        # data segment selector | .set PROT_MODE_DSEG,0x10        # data segment selector | ||||||
| .set CR0_PE_ON,0x1		# protected mode enable flag | .set CR0_PE_ON,0x1              # protected mode enable flag | ||||||
| 	 |          | ||||||
| ################################################################################### | ################################################################################### | ||||||
| # ENTRY POINT	 | # ENTRY POINT    | ||||||
| #   This code should be stored in the first sector of the hard disk. | #   This code should be stored in the first sector of the hard disk. | ||||||
| #   After the BIOS initializes the hardware on startup or system reset, | #   After the BIOS initializes the hardware on startup or system reset, | ||||||
| #   it loads this code at physical address 0x7c00 - 0x7d00 (512 bytes). | #   it loads this code at physical address 0x7c00 - 0x7d00 (512 bytes). | ||||||
| #   Then the BIOS jumps to the beginning of it, address 0x7c00, | #   Then the BIOS jumps to the beginning of it, address 0x7c00, | ||||||
| #   while running in 16-bit real-mode (8086 compatibility mode). | #   while running in 16-bit real-mode (8086 compatibility mode). | ||||||
| #   The Code Segment register (CS) is initially zero on entry. | #   The Code Segment register (CS) is initially zero on entry. | ||||||
| #	 | #        | ||||||
| # This code switches into 32-bit protected mode so that all of | # This code switches into 32-bit protected mode so that all of | ||||||
| # memory can accessed, then calls into C. | # memory can accessed, then calls into C. | ||||||
| ################################################################################### | ################################################################################### | ||||||
| 	 |          | ||||||
| .globl start					# Entry point	 | .globl start                      # Entry point    | ||||||
| start:		.code16				# This runs in real mode | start: | ||||||
| 		cli				# Disable interrupts | .code16                           # This runs in real mode | ||||||
| 		cld				# String operations increment |   cli                             # Disable interrupts | ||||||
|  |   cld                             # String operations increment | ||||||
| 
 | 
 | ||||||
| 		# Set up the important data segment registers (DS, ES, SS). |   # Set up the important data segment registers (DS, ES, SS). | ||||||
| 		xorw	%ax,%ax			# Segment number zero |   xorw    %ax,%ax                 # Segment number zero | ||||||
| 		movw	%ax,%ds			# -> Data Segment |   movw    %ax,%ds                 # -> Data Segment | ||||||
| 		movw	%ax,%es			# -> Extra Segment |   movw    %ax,%es                 # -> Extra Segment | ||||||
| 		movw	%ax,%ss			# -> Stack Segment |   movw    %ax,%ss                 # -> Stack Segment | ||||||
| 
 | 
 | ||||||
| 		# Set up the stack pointer, growing downward from 0x7c00. |   # Set up the stack pointer, growing downward from 0x7c00. | ||||||
| 		movw	$start,%sp         	# Stack Pointer |   movw    $start,%sp              # Stack Pointer | ||||||
| 	 |          | ||||||
| #### Enable A20: | #### Enable A20: | ||||||
| ####   For fascinating historical reasons (related to the fact that | ####   For fascinating historical reasons (related to the fact that | ||||||
| ####   the earliest 8086-based PCs could only address 1MB of physical memory | ####   the earliest 8086-based PCs could only address 1MB of physical memory | ||||||
|  | @ -38,59 +39,65 @@ start:		.code16				# This runs in real mode | ||||||
| ####   physical address line 20 is tied to low when the machine boots. | ####   physical address line 20 is tied to low when the machine boots. | ||||||
| ####   Obviously this a bit of a drag for us, especially when trying to | ####   Obviously this a bit of a drag for us, especially when trying to | ||||||
| ####   address memory above 1MB.  This code undoes this. | ####   address memory above 1MB.  This code undoes this. | ||||||
| 	 |          | ||||||
| seta20.1:	inb	$0x64,%al		# Get status | seta20.1: | ||||||
| 		testb	$0x2,%al		# Busy? |   inb     $0x64,%al               # Get status | ||||||
| 		jnz	seta20.1		# Yes |   testb   $0x2,%al                # Busy? | ||||||
| 		movb	$0xd1,%al		# Command: Write |   jnz     seta20.1                # Yes | ||||||
| 		outb	%al,$0x64		#  output port |   movb    $0xd1,%al               # Command: Write | ||||||
| seta20.2:	inb	$0x64,%al		# Get status |   outb    %al,$0x64               #  output port | ||||||
| 		testb	$0x2,%al		# Busy? |  | ||||||
| 		jnz	seta20.2		# Yes |  | ||||||
| 		movb	$0xdf,%al		# Enable |  | ||||||
| 		outb	%al,$0x60		#  A20 |  | ||||||
| 
 | 
 | ||||||
| #### Switch from real to protected mode	 | seta20.2: | ||||||
|  |   inb     $0x64,%al               # Get status | ||||||
|  |   testb   $0x2,%al                # Busy? | ||||||
|  |   jnz     seta20.2                # Yes | ||||||
|  |   movb    $0xdf,%al               # Enable | ||||||
|  |   outb    %al,$0x60               #  A20 | ||||||
|  | 
 | ||||||
|  | #### Switch from real to protected mode  | ||||||
| ####     The descriptors in our GDT allow all physical memory to be accessed. | ####     The descriptors in our GDT allow all physical memory to be accessed. | ||||||
| ####     Furthermore, the descriptors have base addresses of 0, so that the | ####     Furthermore, the descriptors have base addresses of 0, so that the | ||||||
| ####     segment translation is a NOP, ie. virtual addresses are identical to | ####     segment translation is a NOP, ie. virtual addresses are identical to | ||||||
| ####     their physical addresses.  With this setup, immediately after | ####     their physical addresses.  With this setup, immediately after | ||||||
| ####	 enabling protected mode it will still appear to this code | ####     enabling protected mode it will still appear to this code | ||||||
| ####	 that it is running directly on physical memory with no translation. | ####     that it is running directly on physical memory with no translation. | ||||||
| ####	 This initial NOP-translation setup is required by the processor | ####     This initial NOP-translation setup is required by the processor | ||||||
| ####	 to ensure that the transition to protected mode occurs smoothly. | ####     to ensure that the transition to protected mode occurs smoothly. | ||||||
| 	 |          | ||||||
| real_to_prot:	cli				# Mandatory since we dont set up an IDT | real_to_prot: | ||||||
| 		lgdt	gdtdesc			# load GDT -- mandatory in protected mode |   cli                             # Mandatory since we dont set up an IDT | ||||||
| 		movl	%cr0, %eax		# turn on protected mode |   lgdt    gdtdesc                 # load GDT -- mandatory in protected mode | ||||||
| 		orl	$CR0_PE_ON, %eax	#  |   movl    %cr0, %eax              # turn on protected mode | ||||||
| 		movl	%eax, %cr0		#  |   orl     $CR0_PE_ON, %eax        #  | ||||||
| 	        ### CPU magic: jump to relocation, flush prefetch queue, and reload %cs |   movl    %eax, %cr0              #  | ||||||
| 		### Has the effect of just jmp to the next instruction, but simultaneous |   ### CPU magic: jump to relocation, flush prefetch queue, and reload %cs | ||||||
| 		### loads CS with $PROT_MODE_CSEG. |   ### Has the effect of just jmp to the next instruction, but simultaneous | ||||||
| 		ljmp	$PROT_MODE_CSEG, $protcseg |   ### loads CS with $PROT_MODE_CSEG. | ||||||
| 	 |   ljmp    $PROT_MODE_CSEG, $protcseg | ||||||
|  |          | ||||||
| #### we are in 32-bit protected mode (hence the .code32) | #### we are in 32-bit protected mode (hence the .code32) | ||||||
| .code32 | .code32 | ||||||
| protcseg:	 | protcseg:        | ||||||
| 		# Set up the protected-mode data segment registers |   # Set up the protected-mode data segment registers | ||||||
| 		movw	$PROT_MODE_DSEG, %ax	# Our data segment selector |   movw    $PROT_MODE_DSEG, %ax    # Our data segment selector | ||||||
| 		movw	%ax, %ds		# -> DS: Data Segment |   movw    %ax, %ds                # -> DS: Data Segment | ||||||
| 		movw	%ax, %es		# -> ES: Extra Segment |   movw    %ax, %es                # -> ES: Extra Segment | ||||||
| 		movw	%ax, %fs		# -> FS |   movw    %ax, %fs                # -> FS | ||||||
| 		movw	%ax, %gs		# -> GS |   movw    %ax, %gs                # -> GS | ||||||
| 		movw	%ax, %ss		# -> SS: Stack Segment |   movw    %ax, %ss                # -> SS: Stack Segment | ||||||
| 	 | 
 | ||||||
| 		call cmain			# finish the boot load from C. |   call cmain                      # finish the boot load from C. | ||||||
| 						# cmain() should not return |                                   # cmain() should not return | ||||||
| spin:		jmp spin			# ..but in case it does, spin | spin: | ||||||
| 	 |   jmp spin                        # ..but in case it does, spin | ||||||
| .p2align 2					# force 4 byte alignment | 
 | ||||||
|  | 
 | ||||||
|  | .p2align 2                                # force 4 byte alignment | ||||||
| gdt: | gdt: | ||||||
| 	SEG_NULLASM				# null seg |   SEG_NULLASM                             # null seg | ||||||
| 	SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)	# code seg |   SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)   # code seg | ||||||
| 	SEG_ASM(STA_W, 0x0, 0xffffffff)	        # data seg |   SEG_ASM(STA_W, 0x0, 0xffffffff)         # data seg | ||||||
| 	 |          | ||||||
| gdtdesc: | gdtdesc: | ||||||
| 	.word	0x17			# sizeof(gdt) - 1 |   .word   0x17                            # sizeof(gdt) - 1 | ||||||
| 	.long	gdt			# address gdt |   .long   gdt                             # address gdt | ||||||
|  |  | ||||||
							
								
								
									
										106
									
								
								bootmain.c
									
										
									
									
									
								
							
							
						
						
									
										106
									
								
								bootmain.c
									
										
									
									
									
								
							|  | @ -11,10 +11,10 @@ | ||||||
|  *    be stored in the first sector of the disk. |  *    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	 |  * BOOT UP STEPS   | ||||||
|  *  * when the CPU boots it loads the BIOS into memory and executes it |  *  * when the CPU boots it loads the BIOS into memory and executes it | ||||||
|  * |  * | ||||||
|  *  * the BIOS intializes devices, sets of the interrupt routines, and |  *  * the BIOS intializes devices, sets of the interrupt routines, and | ||||||
|  | @ -30,8 +30,8 @@ | ||||||
|  *  * 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
 | ||||||
| 
 | 
 | ||||||
| void readsect(void*, uint); | void readsect(void*, uint); | ||||||
| void readseg(uint, uint, uint); | void readseg(uint, uint, uint); | ||||||
|  | @ -39,30 +39,30 @@ void readseg(uint, uint, uint); | ||||||
| void | void | ||||||
| cmain(void) | cmain(void) | ||||||
| { | { | ||||||
| 	struct proghdr *ph, *eph; |   struct proghdr *ph, *eph; | ||||||
| 
 | 
 | ||||||
| 	// read 1st page off disk
 |   // read 1st page off disk
 | ||||||
| 	readseg((uint) ELFHDR, SECTSIZE*8, 0); |   readseg((uint) ELFHDR, SECTSIZE*8, 0); | ||||||
| 
 | 
 | ||||||
| 	// is this a valid ELF?
 |   // is this a valid ELF?
 | ||||||
| 	if (ELFHDR->magic != ELF_MAGIC) |   if (ELFHDR->magic != ELF_MAGIC) | ||||||
| 		goto bad; |     goto bad; | ||||||
| 
 | 
 | ||||||
| 	// load each program segment (ignores ph flags)
 |   // load each program segment (ignores ph flags)
 | ||||||
| 	ph = (struct proghdr *) ((uchar *) ELFHDR + ELFHDR->phoff); |   ph = (struct proghdr *) ((uchar *) ELFHDR + ELFHDR->phoff); | ||||||
| 	eph = ph + ELFHDR->phnum; |   eph = ph + ELFHDR->phnum; | ||||||
| 	for (; ph < eph; ph++) |   for (; ph < eph; ph++) | ||||||
| 		readseg(ph->va, ph->memsz, ph->offset); |     readseg(ph->va, ph->memsz, ph->offset); | ||||||
| 
 | 
 | ||||||
| 	// call the entry point from the ELF header
 |   // call the entry point from the ELF header
 | ||||||
| 	// note: does not return!
 |   // note: does not return!
 | ||||||
| 	((void (*)(void)) (ELFHDR->entry & 0xFFFFFF))(); |   ((void (*)(void)) (ELFHDR->entry & 0xFFFFFF))(); | ||||||
| 
 | 
 | ||||||
| bad: | bad: | ||||||
| 	outw(0x8A00, 0x8A00); |   outw(0x8A00, 0x8A00); | ||||||
| 	outw(0x8A00, 0x8E00); |   outw(0x8A00, 0x8E00); | ||||||
| 	while(1) |   while(1) | ||||||
| 		/* do nothing */; |     /* do nothing */; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
 | // Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
 | ||||||
|  | @ -70,52 +70,52 @@ bad: | ||||||
| void | void | ||||||
| readseg(uint va, uint count, uint offset) | readseg(uint va, uint count, uint offset) | ||||||
| { | { | ||||||
| 	uint end_va; |   uint end_va; | ||||||
| 
 | 
 | ||||||
| 	va &= 0xFFFFFF; |   va &= 0xFFFFFF; | ||||||
| 	end_va = va + count; |   end_va = va + count; | ||||||
| 	 |    | ||||||
| 	// round down to sector boundary
 |   // round down to sector boundary
 | ||||||
| 	va &= ~(SECTSIZE - 1); |   va &= ~(SECTSIZE - 1); | ||||||
| 
 | 
 | ||||||
| 	// translate from bytes to sectors, and kernel starts at sector 1
 |   // translate from bytes to sectors, and kernel starts at sector 1
 | ||||||
| 	offset = (offset / SECTSIZE) + 1; |   offset = (offset / SECTSIZE) + 1; | ||||||
| 
 | 
 | ||||||
| 	// If this is too slow, we could read lots of sectors at a time.
 |   // If this is too slow, we could read lots of sectors at a time.
 | ||||||
| 	// We'd write more to memory than asked, but it doesn't matter --
 |   // We'd write more to memory than asked, but it doesn't matter --
 | ||||||
| 	// we load in increasing order.
 |   // we load in increasing order.
 | ||||||
| 	while (va < end_va) { |   while (va < end_va) { | ||||||
| 		readsect((uchar*) va, offset); |     readsect((uchar*) va, offset); | ||||||
| 		va += SECTSIZE; |     va += SECTSIZE; | ||||||
| 		offset++; |     offset++; | ||||||
| 	} |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| waitdisk(void) | waitdisk(void) | ||||||
| { | { | ||||||
| 	// wait for disk reaady
 |   // wait for disk reaady
 | ||||||
| 	while ((inb(0x1F7) & 0xC0) != 0x40) |   while ((inb(0x1F7) & 0xC0) != 0x40) | ||||||
| 		/* do nothing */; |     /* do nothing */; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| readsect(void *dst, uint offset) | readsect(void *dst, uint offset) | ||||||
| { | { | ||||||
| 	// wait for disk to be ready
 |   // wait for disk to be ready
 | ||||||
| 	waitdisk(); |   waitdisk(); | ||||||
| 
 | 
 | ||||||
| 	outb(0x1F2, 1);		// count = 1
 |   outb(0x1F2, 1);   // count = 1
 | ||||||
| 	outb(0x1F3, offset); |   outb(0x1F3, offset); | ||||||
| 	outb(0x1F4, offset >> 8); |   outb(0x1F4, offset >> 8); | ||||||
| 	outb(0x1F5, offset >> 16); |   outb(0x1F5, offset >> 16); | ||||||
| 	outb(0x1F6, (offset >> 24) | 0xE0); |   outb(0x1F6, (offset >> 24) | 0xE0); | ||||||
| 	outb(0x1F7, 0x20);	// cmd 0x20 - read sectors
 |   outb(0x1F7, 0x20);  // cmd 0x20 - read sectors
 | ||||||
| 
 | 
 | ||||||
| 	// wait for disk to be ready
 |   // wait for disk to be ready
 | ||||||
| 	waitdisk(); |   waitdisk(); | ||||||
| 
 | 
 | ||||||
| 	// read a sector
 |   // read a sector
 | ||||||
| 	insl(0x1F0, dst, SECTSIZE/4); |   insl(0x1F0, dst, SECTSIZE/4); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										99
									
								
								bootother.S
									
										
									
									
									
								
							
							
						
						
									
										99
									
								
								bootother.S
									
										
									
									
									
								
							|  | @ -1,5 +1,5 @@ | ||||||
| #include "asm.h" | #include "asm.h" | ||||||
| 	 |          | ||||||
| /* | /* | ||||||
|  * Start an Application Processor. This must be placed on a 4KB boundary |  * Start an Application Processor. This must be placed on a 4KB boundary | ||||||
|  * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However, |  * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However, | ||||||
|  | @ -13,67 +13,68 @@ | ||||||
|  * mp.c causes each non-boot CPU in turn to jump to start. |  * mp.c causes each non-boot CPU in turn to jump to start. | ||||||
|  * mp.c puts the correct %esp in start-4, and the place to jump |  * mp.c puts the correct %esp in start-4, and the place to jump | ||||||
|  * to in start-8. |  * to in start-8. | ||||||
|  *	 |  *       | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| .set PROT_MODE_CSEG,0x8		# code segment selector | .set PROT_MODE_CSEG,0x8         # code segment selector | ||||||
| .set PROT_MODE_DSEG,0x10        # data segment selector | .set PROT_MODE_DSEG,0x10        # data segment selector | ||||||
| .set CR0_PE_ON,0x1		# protected mode enable flag | .set CR0_PE_ON,0x1              # protected mode enable flag | ||||||
| 
 | 
 | ||||||
| .globl start
 | .globl start
 | ||||||
| start:		.code16				# This runs in real mode | start: | ||||||
| 		cli				# Disable interrupts |   .code16                         # This runs in real mode | ||||||
| 		cld				# String operations increment |   cli                             # Disable interrupts | ||||||
|  |   cld                             # String operations increment | ||||||
| 
 | 
 | ||||||
| 		# Set up the important data segment registers (DS, ES, SS). |   # Set up the important data segment registers (DS, ES, SS). | ||||||
| 		xorw	%ax,%ax			# Segment number zero |   xorw    %ax,%ax                 # Segment number zero | ||||||
| 		movw	%ax,%ds			# -> Data Segment |   movw    %ax,%ds                 # -> Data Segment | ||||||
| 		movw	%ax,%es			# -> Extra Segment |   movw    %ax,%es                 # -> Extra Segment | ||||||
| 		movw	%ax,%ss			# -> Stack Segment |   movw    %ax,%ss                 # -> Stack Segment | ||||||
| 
 | 
 | ||||||
| 		# Set up the stack pointer, growing downward from 0x7000-8. |   # Set up the stack pointer, growing downward from 0x7000-8. | ||||||
| 		movw	$start-8,%sp         	# Stack Pointer |   movw    $start-8,%sp            # Stack Pointer | ||||||
| 	 |          | ||||||
| #### Switch from real to protected mode	 | #### Switch from real to protected mode  | ||||||
| ####     The descriptors in our GDT allow all physical memory to be accessed. | ####     The descriptors in our GDT allow all physical memory to be accessed. | ||||||
| ####     Furthermore, the descriptors have base addresses of 0, so that the | ####     Furthermore, the descriptors have base addresses of 0, so that the | ||||||
| ####     segment translation is a NOP, ie. virtual addresses are identical to | ####     segment translation is a NOP, ie. virtual addresses are identical to | ||||||
| ####     their physical addresses.  With this setup, immediately after | ####     their physical addresses.  With this setup, immediately after | ||||||
| ####	 enabling protected mode it will still appear to this code | ####     enabling protected mode it will still appear to this code | ||||||
| ####	 that it is running directly on physical memory with no translation. | ####     that it is running directly on physical memory with no translation. | ||||||
| ####	 This initial NOP-translation setup is required by the processor | ####     This initial NOP-translation setup is required by the processor | ||||||
| ####	 to ensure that the transition to protected mode occurs smoothly. | ####     to ensure that the transition to protected mode occurs smoothly. | ||||||
| 	 |          | ||||||
| 		lgdt	gdtdesc			# load GDT -- mandatory in protected mode |   lgdt    gdtdesc                 # load GDT -- mandatory in protected mode | ||||||
| 		movl	%cr0, %eax		# turn on protected mode |   movl    %cr0, %eax              # turn on protected mode | ||||||
| 		orl	$CR0_PE_ON, %eax	#  |   orl     $CR0_PE_ON, %eax        #  | ||||||
| 		movl	%eax, %cr0		#  |   movl    %eax, %cr0              #  | ||||||
| 	        ### CPU magic: jump to relocation, flush prefetch queue, and reload %cs |   ### CPU magic: jump to relocation, flush prefetch queue, and reload %cs | ||||||
| 		### Has the effect of just jmp to the next instruction, but simultaneous |   ### Has the effect of just jmp to the next instruction, but simultaneous | ||||||
| 		### loads CS with $PROT_MODE_CSEG. |   ### loads CS with $PROT_MODE_CSEG. | ||||||
| 		ljmp	$PROT_MODE_CSEG, $protcseg |   ljmp    $PROT_MODE_CSEG, $protcseg | ||||||
| 	 | 
 | ||||||
| #### we are in 32-bit protected mode (hence the .code32) | #### we are in 32-bit protected mode (hence the .code32) | ||||||
| .code32 | .code32 | ||||||
| protcseg:	 | protcseg:        | ||||||
| 		# Set up the protected-mode data segment registers |   # Set up the protected-mode data segment registers | ||||||
| 		movw	$PROT_MODE_DSEG, %ax	# Our data segment selector |   movw    $PROT_MODE_DSEG, %ax    # Our data segment selector | ||||||
| 		movw	%ax, %ds		# -> DS: Data Segment |   movw    %ax, %ds                # -> DS: Data Segment | ||||||
| 		movw	%ax, %es		# -> ES: Extra Segment |   movw    %ax, %es                # -> ES: Extra Segment | ||||||
| 		movw	%ax, %fs		# -> FS |   movw    %ax, %fs                # -> FS | ||||||
| 		movw	%ax, %gs		# -> GS |   movw    %ax, %gs                # -> GS | ||||||
| 		movw	%ax, %ss		# -> SS: Stack Segment |   movw    %ax, %ss                # -> SS: Stack Segment | ||||||
| 
 | 
 | ||||||
|                 movl    start-8, %eax |   movl    start-8, %eax | ||||||
|                 movl    start-4, %esp |   movl    start-4, %esp | ||||||
| 		jmp	*%eax                    |   jmp     *%eax                    | ||||||
| 	 |          | ||||||
| .p2align 2					# force 4 byte alignment | .p2align 2                                 # force 4 byte alignment | ||||||
| gdt: | gdt: | ||||||
| 	SEG_NULLASM				# null seg |   SEG_NULLASM                             # null seg | ||||||
| 	SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)	# code seg |   SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)   # code seg | ||||||
| 	SEG_ASM(STA_W, 0x0, 0xffffffff)	        # data seg |   SEG_ASM(STA_W, 0x0, 0xffffffff)         # data seg | ||||||
| 	 |          | ||||||
| gdtdesc: | gdtdesc: | ||||||
| 	.word	0x17			# sizeof(gdt) - 1 |   .word   0x17                            # sizeof(gdt) - 1 | ||||||
| 	.long	gdt			# address gdt |   .long   gdt                             # address gdt | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								cat.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								cat.c
									
										
									
									
									
								
							|  | @ -30,10 +30,10 @@ main(int argc, char *argv[]) | ||||||
|     for(i = 1; i < argc; i++){ |     for(i = 1; i < argc; i++){ | ||||||
|       fd = open(argv[i], 0); |       fd = open(argv[i], 0); | ||||||
|       if(fd < 0){ |       if(fd < 0){ | ||||||
| 	puts("cat: cannot open "); |         puts("cat: cannot open "); | ||||||
| 	puts(argv[i]); |         puts(argv[i]); | ||||||
| 	puts("\n"); |         puts("\n"); | ||||||
| 	exit(); |         exit(); | ||||||
|       } |       } | ||||||
|       rfile(fd); |       rfile(fd); | ||||||
|       close(fd); |       close(fd); | ||||||
|  |  | ||||||
							
								
								
									
										174
									
								
								console.c
									
										
									
									
									
								
							
							
						
						
									
										174
									
								
								console.c
									
										
									
									
									
								
							|  | @ -18,13 +18,13 @@ int use_console_lock = 0; | ||||||
| static void | static void | ||||||
| lpt_putc(int c) | lpt_putc(int c) | ||||||
| { | { | ||||||
| 	int i; |   int i; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++) |   for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++) | ||||||
| 		; |     ; | ||||||
| 	outb(0x378+0, c); |   outb(0x378+0, c); | ||||||
| 	outb(0x378+2, 0x08|0x04|0x01); |   outb(0x378+2, 0x08|0x04|0x01); | ||||||
| 	outb(0x378+2, 0x08); |   outb(0x378+2, 0x08); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
|  | @ -183,117 +183,117 @@ 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 | ||||||
| 
 | 
 | ||||||
| #define SHIFT		(1<<0) | #define SHIFT           (1<<0) | ||||||
| #define CTL		(1<<1) | #define CTL             (1<<1) | ||||||
| #define ALT		(1<<2) | #define ALT             (1<<2) | ||||||
| 
 | 
 | ||||||
| #define CAPSLOCK	(1<<3) | #define CAPSLOCK        (1<<3) | ||||||
| #define NUMLOCK		(1<<4) | #define NUMLOCK         (1<<4) | ||||||
| #define SCROLLLOCK	(1<<5) | #define SCROLLLOCK      (1<<5) | ||||||
| 
 | 
 | ||||||
| #define E0ESC		(1<<6) | #define E0ESC           (1<<6) | ||||||
| 
 | 
 | ||||||
| // Special keycodes
 | // Special keycodes
 | ||||||
| #define KEY_HOME	0xE0 | #define KEY_HOME        0xE0 | ||||||
| #define KEY_END		0xE1 | #define KEY_END         0xE1 | ||||||
| #define KEY_UP		0xE2 | #define KEY_UP          0xE2 | ||||||
| #define KEY_DN		0xE3 | #define KEY_DN          0xE3 | ||||||
| #define KEY_LF		0xE4 | #define KEY_LF          0xE4 | ||||||
| #define KEY_RT		0xE5 | #define KEY_RT          0xE5 | ||||||
| #define KEY_PGUP	0xE6 | #define KEY_PGUP        0xE6 | ||||||
| #define KEY_PGDN	0xE7 | #define KEY_PGDN        0xE7 | ||||||
| #define KEY_INS		0xE8 | #define KEY_INS         0xE8 | ||||||
| #define KEY_DEL		0xE9 | #define KEY_DEL         0xE9 | ||||||
| 
 | 
 | ||||||
| static uchar shiftcode[256] =  | static uchar shiftcode[256] =  | ||||||
| { | { | ||||||
| 	[0x1D] CTL, |   [0x1D] CTL, | ||||||
| 	[0x2A] SHIFT, |   [0x2A] SHIFT, | ||||||
| 	[0x36] SHIFT, |   [0x36] SHIFT, | ||||||
| 	[0x38] ALT, |   [0x38] ALT, | ||||||
| 	[0x9D] CTL, |   [0x9D] CTL, | ||||||
| 	[0xB8] ALT |   [0xB8] ALT | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uchar togglecode[256] =  | static uchar togglecode[256] =  | ||||||
| { | { | ||||||
| 	[0x3A] CAPSLOCK, |   [0x3A] CAPSLOCK, | ||||||
| 	[0x45] NUMLOCK, |   [0x45] NUMLOCK, | ||||||
| 	[0x46] SCROLLLOCK |   [0x46] SCROLLLOCK | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uchar normalmap[256] = | static uchar normalmap[256] = | ||||||
| { | { | ||||||
| 	NO,   0x1B, '1',  '2',  '3',  '4',  '5',  '6',	// 0x00
 |   NO,   0x1B, '1',  '2',  '3',  '4',  '5',  '6',  // 0x00
 | ||||||
| 	'7',  '8',  '9',  '0',  '-',  '=',  '\b', '\t', |   '7',  '8',  '9',  '0',  '-',  '=',  '\b', '\t', | ||||||
| 	'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',	// 0x10
 |   'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',  // 0x10
 | ||||||
| 	'o',  'p',  '[',  ']',  '\n', NO,   'a',  's', |   'o',  'p',  '[',  ']',  '\n', NO,   'a',  's', | ||||||
| 	'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',	// 0x20
 |   'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',  // 0x20
 | ||||||
| 	'\'', '`',  NO,   '\\', 'z',  'x',  'c',  'v', |   '\'', '`',  NO,   '\\', 'z',  'x',  'c',  'v', | ||||||
| 	'b',  'n',  'm',  ',',  '.',  '/',  NO,   '*',	// 0x30
 |   'b',  'n',  'm',  ',',  '.',  '/',  NO,   '*',  // 0x30
 | ||||||
| 	NO,   ' ',  NO,   NO,   NO,   NO,   NO,   NO, |   NO,   ' ',  NO,   NO,   NO,   NO,   NO,   NO, | ||||||
| 	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,  [0x9C] '\n' /*KP_Enter*/, | ||||||
| 	[0xB5] '/' /*KP_Div*/,	[0xC8] KEY_UP, |   [0xB5] '/' /*KP_Div*/,  [0xC8] KEY_UP, | ||||||
| 	[0xC9] KEY_PGUP,	[0xCB] KEY_LF, |   [0xC9] KEY_PGUP,  [0xCB] KEY_LF, | ||||||
| 	[0xCD] KEY_RT,		[0xCF] KEY_END, |   [0xCD] KEY_RT,    [0xCF] KEY_END, | ||||||
| 	[0xD0] KEY_DN,		[0xD1] KEY_PGDN, |   [0xD0] KEY_DN,    [0xD1] KEY_PGDN, | ||||||
| 	[0xD2] KEY_INS,		[0xD3] KEY_DEL |   [0xD2] KEY_INS,   [0xD3] KEY_DEL | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uchar shiftmap[256] =  | static uchar shiftmap[256] =  | ||||||
| { | { | ||||||
| 	NO,   033,  '!',  '@',  '#',  '$',  '%',  '^',	// 0x00
 |   NO,   033,  '!',  '@',  '#',  '$',  '%',  '^',  // 0x00
 | ||||||
| 	'&',  '*',  '(',  ')',  '_',  '+',  '\b', '\t', |   '&',  '*',  '(',  ')',  '_',  '+',  '\b', '\t', | ||||||
| 	'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',	// 0x10
 |   'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',  // 0x10
 | ||||||
| 	'O',  'P',  '{',  '}',  '\n', NO,   'A',  'S', |   'O',  'P',  '{',  '}',  '\n', NO,   'A',  'S', | ||||||
| 	'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',	// 0x20
 |   'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',  // 0x20
 | ||||||
| 	'"',  '~',  NO,   '|',  'Z',  'X',  'C',  'V', |   '"',  '~',  NO,   '|',  'Z',  'X',  'C',  'V', | ||||||
| 	'B',  'N',  'M',  '<',  '>',  '?',  NO,   '*',	// 0x30
 |   'B',  'N',  'M',  '<',  '>',  '?',  NO,   '*',  // 0x30
 | ||||||
| 	NO,   ' ',  NO,   NO,   NO,   NO,   NO,   NO, |   NO,   ' ',  NO,   NO,   NO,   NO,   NO,   NO, | ||||||
| 	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,  [0x9C] '\n' /*KP_Enter*/, | ||||||
| 	[0xB5] '/' /*KP_Div*/,	[0xC8] KEY_UP, |   [0xB5] '/' /*KP_Div*/,  [0xC8] KEY_UP, | ||||||
| 	[0xC9] KEY_PGUP,	[0xCB] KEY_LF, |   [0xC9] KEY_PGUP,  [0xCB] KEY_LF, | ||||||
| 	[0xCD] KEY_RT,		[0xCF] KEY_END, |   [0xCD] KEY_RT,    [0xCF] KEY_END, | ||||||
| 	[0xD0] KEY_DN,		[0xD1] KEY_PGDN, |   [0xD0] KEY_DN,    [0xD1] KEY_PGDN, | ||||||
| 	[0xD2] KEY_INS,		[0xD3] KEY_DEL |   [0xD2] KEY_INS,   [0xD3] KEY_DEL | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define C(x) (x - '@') | #define C(x) (x - '@') | ||||||
| 
 | 
 | ||||||
| static uchar ctlmap[256] =  | static uchar ctlmap[256] =  | ||||||
| { | { | ||||||
| 	NO,      NO,      NO,      NO,      NO,      NO,      NO,      NO,  |   NO,      NO,      NO,      NO,      NO,      NO,      NO,      NO,  | ||||||
| 	NO,      NO,      NO,      NO,      NO,      NO,      NO,      NO,  |   NO,      NO,      NO,      NO,      NO,      NO,      NO,      NO,  | ||||||
| 	C('Q'),  C('W'),  C('E'),  C('R'),  C('T'),  C('Y'),  C('U'),  C('I'), |   C('Q'),  C('W'),  C('E'),  C('R'),  C('T'),  C('Y'),  C('U'),  C('I'), | ||||||
| 	C('O'),  C('P'),  NO,      NO,      '\r',    NO,      C('A'),  C('S'), |   C('O'),  C('P'),  NO,      NO,      '\r',    NO,      C('A'),  C('S'), | ||||||
| 	C('D'),  C('F'),  C('G'),  C('H'),  C('J'),  C('K'),  C('L'),  NO,  |   C('D'),  C('F'),  C('G'),  C('H'),  C('J'),  C('K'),  C('L'),  NO,  | ||||||
| 	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('/'),    [0xC8] KEY_UP, | ||||||
| 	[0xC9] KEY_PGUP,	[0xCB] KEY_LF, |   [0xC9] KEY_PGUP,  [0xCB] KEY_LF, | ||||||
| 	[0xCD] KEY_RT,		[0xCF] KEY_END, |   [0xCD] KEY_RT,    [0xCF] KEY_END, | ||||||
| 	[0xD0] KEY_DN,		[0xD1] KEY_PGDN, |   [0xD0] KEY_DN,    [0xD1] KEY_PGDN, | ||||||
| 	[0xD2] KEY_INS,		[0xD3] KEY_DEL |   [0xD2] KEY_INS,   [0xD3] KEY_DEL | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static uchar *charcode[4] = { | static uchar *charcode[4] = { | ||||||
| 	normalmap, |   normalmap, | ||||||
| 	shiftmap, |   shiftmap, | ||||||
| 	ctlmap, |   ctlmap, | ||||||
| 	ctlmap |   ctlmap | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define KBD_BUF 64 | #define KBD_BUF 64 | ||||||
|  |  | ||||||
							
								
								
									
										46
									
								
								elf.h
									
										
									
									
									
								
							
							
						
						
									
										46
									
								
								elf.h
									
										
									
									
									
								
							|  | @ -5,32 +5,32 @@ | ||||||
| #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
 | ||||||
| 	uchar elf[12]; |   uchar elf[12]; | ||||||
| 	ushort type; |   ushort type; | ||||||
| 	ushort machine; |   ushort machine; | ||||||
| 	uint version; |   uint version; | ||||||
| 	uint entry; |   uint entry; | ||||||
| 	uint phoff; |   uint phoff; | ||||||
| 	uint shoff; |   uint shoff; | ||||||
| 	uint flags; |   uint flags; | ||||||
| 	ushort ehsize; |   ushort ehsize; | ||||||
| 	ushort phentsize; |   ushort phentsize; | ||||||
| 	ushort phnum; |   ushort phnum; | ||||||
| 	ushort shentsize; |   ushort shentsize; | ||||||
| 	ushort shnum; |   ushort shnum; | ||||||
| 	ushort shstrndx; |   ushort shstrndx; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct proghdr { | struct proghdr { | ||||||
| 	uint type; |   uint type; | ||||||
| 	uint offset; |   uint offset; | ||||||
| 	uint va; |   uint va; | ||||||
| 	uint pa; |   uint pa; | ||||||
| 	uint filesz; |   uint filesz; | ||||||
| 	uint memsz; |   uint memsz; | ||||||
| 	uint flags; |   uint flags; | ||||||
| 	uint align; |   uint align; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Values for Proghdr type
 | // Values for Proghdr type
 | ||||||
|  |  | ||||||
							
								
								
									
										26
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								fs.c
									
										
									
									
									
								
							|  | @ -270,16 +270,16 @@ itrunc(struct inode *ip) | ||||||
|   for (i = 0; i < NADDRS; i++) { |   for (i = 0; i < NADDRS; i++) { | ||||||
|     if (ip->addrs[i] != 0) { |     if (ip->addrs[i] != 0) { | ||||||
|       if (i == INDIRECT) { |       if (i == INDIRECT) { | ||||||
| 	inbp = bread(ip->dev, ip->addrs[INDIRECT]); |         inbp = bread(ip->dev, ip->addrs[INDIRECT]); | ||||||
|         uint *a = (uint *) inbp->data; |         uint *a = (uint *) inbp->data; | ||||||
| 	for (j = 0; j < NINDIRECT; j++) { |         for (j = 0; j < NINDIRECT; j++) { | ||||||
| 	  if (a[j] != 0) { |           if (a[j] != 0) { | ||||||
| 	    bfree(ip->dev, a[j]); |             bfree(ip->dev, a[j]); | ||||||
| 	    a[j] = 0; |             a[j] = 0; | ||||||
| 	  } |           } | ||||||
| 	} |         } | ||||||
| 	brelse(inbp); |         brelse(inbp); | ||||||
|       }	 |       }  | ||||||
|       bfree(ip->dev, ip->addrs[i]); |       bfree(ip->dev, ip->addrs[i]); | ||||||
|       ip->addrs[i] = 0; |       ip->addrs[i] = 0; | ||||||
|     } |     } | ||||||
|  | @ -411,8 +411,8 @@ writei(struct inode *ip, char *addr, uint off, uint n) | ||||||
|       lbn = off / BSIZE; |       lbn = off / BSIZE; | ||||||
|       if (lbn >= MAXFILE) return r; |       if (lbn >= MAXFILE) return r; | ||||||
|       if (newblock(ip, lbn) < 0) { |       if (newblock(ip, lbn) < 0) { | ||||||
| 	cprintf("newblock failed\n"); |         cprintf("newblock failed\n"); | ||||||
| 	return r; |         return r; | ||||||
|       } |       } | ||||||
|       m = min(BSIZE - off % BSIZE, n-r); |       m = min(BSIZE - off % BSIZE, n-r); | ||||||
|       bp = bread(ip->dev, bmap(ip, lbn)); |       bp = bread(ip->dev, bmap(ip, lbn)); | ||||||
|  | @ -424,8 +424,8 @@ writei(struct inode *ip, char *addr, uint off, uint n) | ||||||
|     } |     } | ||||||
|     if (r > 0) { |     if (r > 0) { | ||||||
|       if (off > ip->size) { |       if (off > ip->size) { | ||||||
| 	if (ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE; |         if (ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE; | ||||||
| 	else ip->size = off; |         else ip->size = off; | ||||||
|       } |       } | ||||||
|       iupdate(ip); |       iupdate(ip); | ||||||
|     } |     } | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								ide.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								ide.c
									
										
									
									
									
								
							|  | @ -11,8 +11,8 @@ | ||||||
| #include "traps.h" | #include "traps.h" | ||||||
| #include "spinlock.h" | #include "spinlock.h" | ||||||
| 
 | 
 | ||||||
| #define IDE_BSY		0x80 | #define IDE_BSY     0x80 | ||||||
| #define IDE_DRDY	0x40 | #define IDE_DRDY    0x40 | ||||||
| #define IDE_DF		0x20 | #define IDE_DF		0x20 | ||||||
| #define IDE_ERR		0x01 | #define IDE_ERR		0x01 | ||||||
| 
 | 
 | ||||||
|  | @ -23,6 +23,7 @@ struct ide_request { | ||||||
|   uint nsecs; |   uint nsecs; | ||||||
|   uint read; |   uint read; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
| struct ide_request request[NREQUEST]; | struct ide_request request[NREQUEST]; | ||||||
| int head, tail; | int head, tail; | ||||||
| struct spinlock ide_lock; | struct spinlock ide_lock; | ||||||
|  | @ -154,7 +155,7 @@ int | ||||||
| ide_write(int diskno, uint secno, const void *src, uint nsecs) | ide_write(int diskno, uint secno, const void *src, uint nsecs) | ||||||
| { | { | ||||||
|   int r; |   int r; | ||||||
| 	 | 
 | ||||||
|   if(nsecs > 256) |   if(nsecs > 256) | ||||||
|     panic("ide_write"); |     panic("ide_write"); | ||||||
| 
 | 
 | ||||||
|  | @ -165,7 +166,7 @@ ide_write(int diskno, uint secno, const void *src, uint nsecs) | ||||||
|   outb(0x1F4, (secno >> 8) & 0xFF); |   outb(0x1F4, (secno >> 8) & 0xFF); | ||||||
|   outb(0x1F5, (secno >> 16) & 0xFF); |   outb(0x1F5, (secno >> 16) & 0xFF); | ||||||
|   outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F)); |   outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F)); | ||||||
|   outb(0x1F7, 0x30);	// CMD 0x30 means write sector
 |   outb(0x1F7, 0x30);    // CMD 0x30 means write sector
 | ||||||
| 
 | 
 | ||||||
|   for (; nsecs > 0; nsecs--, src += 512) { |   for (; nsecs > 0; nsecs--, src += 512) { | ||||||
|     if ((r = ide_wait_ready(1)) < 0) |     if ((r = ide_wait_ready(1)) < 0) | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								ioapic.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								ioapic.c
									
										
									
									
									
								
							|  | @ -11,8 +11,8 @@ struct ioapic { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #define	IOAPIC_REDTBL_LO(i)	(IOAPIC_REDTBL + (i) * 2) | #define IOAPIC_REDTBL_LO(i)  (IOAPIC_REDTBL + (i) * 2) | ||||||
| #define	IOAPIC_REDTBL_HI(i)	(IOAPIC_REDTBL_LO(i) + 1) | #define IOAPIC_REDTBL_HI(i)  (IOAPIC_REDTBL_LO(i) + 1) | ||||||
| 
 | 
 | ||||||
| static uint | static uint | ||||||
| ioapic_read(struct ioapic *io, int reg) | ioapic_read(struct ioapic *io, int reg) | ||||||
|  | @ -40,7 +40,7 @@ ioapic_init(void) | ||||||
|   io = (struct ioapic *) IO_APIC_BASE; |   io = (struct ioapic *) IO_APIC_BASE; | ||||||
|   l = ioapic_read(io, IOAPIC_VER); |   l = ioapic_read(io, IOAPIC_VER); | ||||||
|   nintr =  ((l & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1; |   nintr =  ((l & IOART_VER_MAXREDIR) >> MAXREDIRSHIFT) + 1; | ||||||
|   id = ioapic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT;	 |   id = ioapic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT; | ||||||
|   if (id != ioapic_id) |   if (id != ioapic_id) | ||||||
|     panic ("ioapic_init: id isn't equal to ioapic_id\n"); |     panic ("ioapic_init: id isn't equal to ioapic_id\n"); | ||||||
|   for (i = 0; i < nintr; i++) { |   for (i = 0; i < nintr; i++) { | ||||||
|  |  | ||||||
							
								
								
									
										138
									
								
								ioapic.h
									
										
									
									
									
								
							
							
						
						
									
										138
									
								
								ioapic.h
									
										
									
									
									
								
							|  | @ -1,90 +1,90 @@ | ||||||
| #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 | ||||||
| #define	APIC_ID_CLUSTER_ID	0x0f | #define APIC_ID_CLUSTER_ID      0x0f | ||||||
| #define	APIC_MAX_CLUSTER	0xe | #define APIC_MAX_CLUSTER        0xe | ||||||
| #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 | ||||||
| #define IOAPIC_REDTBL		0x10 | #define IOAPIC_REDTBL           0x10 | ||||||
| #define IOAPIC_REDTBL0		IOAPIC_REDTBL | #define IOAPIC_REDTBL0          IOAPIC_REDTBL | ||||||
| #define IOAPIC_REDTBL1		(IOAPIC_REDTBL+0x02) | #define IOAPIC_REDTBL1          (IOAPIC_REDTBL+0x02) | ||||||
| #define IOAPIC_REDTBL2		(IOAPIC_REDTBL+0x04) | #define IOAPIC_REDTBL2          (IOAPIC_REDTBL+0x04) | ||||||
| #define IOAPIC_REDTBL3		(IOAPIC_REDTBL+0x06) | #define IOAPIC_REDTBL3          (IOAPIC_REDTBL+0x06) | ||||||
| #define IOAPIC_REDTBL4		(IOAPIC_REDTBL+0x08) | #define IOAPIC_REDTBL4          (IOAPIC_REDTBL+0x08) | ||||||
| #define IOAPIC_REDTBL5		(IOAPIC_REDTBL+0x0a) | #define IOAPIC_REDTBL5          (IOAPIC_REDTBL+0x0a) | ||||||
| #define IOAPIC_REDTBL6		(IOAPIC_REDTBL+0x0c) | #define IOAPIC_REDTBL6          (IOAPIC_REDTBL+0x0c) | ||||||
| #define IOAPIC_REDTBL7		(IOAPIC_REDTBL+0x0e) | #define IOAPIC_REDTBL7          (IOAPIC_REDTBL+0x0e) | ||||||
| #define IOAPIC_REDTBL8		(IOAPIC_REDTBL+0x10) | #define IOAPIC_REDTBL8          (IOAPIC_REDTBL+0x10) | ||||||
| #define IOAPIC_REDTBL9		(IOAPIC_REDTBL+0x12) | #define IOAPIC_REDTBL9          (IOAPIC_REDTBL+0x12) | ||||||
| #define IOAPIC_REDTBL10		(IOAPIC_REDTBL+0x14) | #define IOAPIC_REDTBL10         (IOAPIC_REDTBL+0x14) | ||||||
| #define IOAPIC_REDTBL11		(IOAPIC_REDTBL+0x16) | #define IOAPIC_REDTBL11         (IOAPIC_REDTBL+0x16) | ||||||
| #define IOAPIC_REDTBL12		(IOAPIC_REDTBL+0x18) | #define IOAPIC_REDTBL12         (IOAPIC_REDTBL+0x18) | ||||||
| #define IOAPIC_REDTBL13		(IOAPIC_REDTBL+0x1a) | #define IOAPIC_REDTBL13         (IOAPIC_REDTBL+0x1a) | ||||||
| #define IOAPIC_REDTBL14		(IOAPIC_REDTBL+0x1c) | #define IOAPIC_REDTBL14         (IOAPIC_REDTBL+0x1c) | ||||||
| #define IOAPIC_REDTBL15		(IOAPIC_REDTBL+0x1e) | #define IOAPIC_REDTBL15         (IOAPIC_REDTBL+0x1e) | ||||||
| #define IOAPIC_REDTBL16		(IOAPIC_REDTBL+0x20) | #define IOAPIC_REDTBL16         (IOAPIC_REDTBL+0x20) | ||||||
| #define IOAPIC_REDTBL17		(IOAPIC_REDTBL+0x22) | #define IOAPIC_REDTBL17         (IOAPIC_REDTBL+0x22) | ||||||
| #define IOAPIC_REDTBL18		(IOAPIC_REDTBL+0x24) | #define IOAPIC_REDTBL18         (IOAPIC_REDTBL+0x24) | ||||||
| #define IOAPIC_REDTBL19		(IOAPIC_REDTBL+0x26) | #define IOAPIC_REDTBL19         (IOAPIC_REDTBL+0x26) | ||||||
| #define IOAPIC_REDTBL20		(IOAPIC_REDTBL+0x28) | #define IOAPIC_REDTBL20         (IOAPIC_REDTBL+0x28) | ||||||
| #define IOAPIC_REDTBL21		(IOAPIC_REDTBL+0x2a) | #define IOAPIC_REDTBL21         (IOAPIC_REDTBL+0x2a) | ||||||
| #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 | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								ls.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								ls.c
									
										
									
									
									
								
							|  | @ -59,17 +59,17 @@ main(int argc, char *argv[]) | ||||||
|     sz = st.st_size; |     sz = st.st_size; | ||||||
|     for(off = 0; off < sz; off += sizeof(struct dirent)) { |     for(off = 0; off < sz; off += sizeof(struct dirent)) { | ||||||
|       if (read(fd, &dirent, sizeof(struct dirent)) != sizeof(struct dirent)) { |       if (read(fd, &dirent, sizeof(struct dirent)) != sizeof(struct dirent)) { | ||||||
| 	printf(1, "ls: read error\n"); |         printf(1, "ls: read error\n"); | ||||||
| 	break; |         break; | ||||||
|       } |       } | ||||||
|       if (dirent.inum != 0) { |       if (dirent.inum != 0) { | ||||||
| 	// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
 |         // xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
 | ||||||
| 	if (stat (dirent.name, &st) < 0)  { |         if (stat (dirent.name, &st) < 0)  { | ||||||
| 	  printf(1, "stat: failed %s\n", dirent.name); |           printf(1, "stat: failed %s\n", dirent.name); | ||||||
| 	  continue; |           continue; | ||||||
| 	} |         } | ||||||
| 	pname(dirent.name); |         pname(dirent.name); | ||||||
| 	printf(1, "%d %d %d\n", st.st_type, dirent.inum, st.st_size); |         printf(1, "%d %d %d\n", st.st_type, dirent.inum, st.st_size); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     break; |     break; | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								main.c
									
										
									
									
									
								
							|  | @ -97,7 +97,7 @@ mpmain(void) | ||||||
|   // make sure there's a TSS
 |   // make sure there's a TSS
 | ||||||
|   setupsegs(0); |   setupsegs(0); | ||||||
| 
 | 
 | ||||||
|   cpuid(0, 0, 0, 0, 0);	// memory barrier
 |   cpuid(0, 0, 0, 0, 0);  // memory barrier
 | ||||||
|   cpus[cpu()].booted = 1; |   cpus[cpu()].booted = 1; | ||||||
| 
 | 
 | ||||||
|   // Enable interrupts on this processor.
 |   // Enable interrupts on this processor.
 | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								mkfs.c
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								mkfs.c
									
										
									
									
									
								
							|  | @ -81,8 +81,8 @@ main(int argc, char *argv[]) | ||||||
|   usedblocks = ninodes / IPB + 3 + bitblocks; |   usedblocks = ninodes / IPB + 3 + bitblocks; | ||||||
|   freeblock = usedblocks; |   freeblock = usedblocks; | ||||||
| 
 | 
 | ||||||
|   printf ("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,  |   printf("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,  | ||||||
| 	  bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks); |          bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks); | ||||||
| 
 | 
 | ||||||
|   assert (nblocks + usedblocks == size); |   assert (nblocks + usedblocks == size); | ||||||
| 
 | 
 | ||||||
|  | @ -246,22 +246,22 @@ iappend(uint inum, void *xp, int n) | ||||||
|     assert(fbn < MAXFILE); |     assert(fbn < MAXFILE); | ||||||
|     if (fbn < NDIRECT) { |     if (fbn < NDIRECT) { | ||||||
|       if(xint(din.addrs[fbn]) == 0) { |       if(xint(din.addrs[fbn]) == 0) { | ||||||
| 	din.addrs[fbn] = xint(freeblock++); |         din.addrs[fbn] = xint(freeblock++); | ||||||
| 	usedblocks++; |         usedblocks++; | ||||||
|       } |       } | ||||||
|       x = xint(din.addrs[fbn]); |       x = xint(din.addrs[fbn]); | ||||||
|     } else { |     } else { | ||||||
|       if(xint(din.addrs[INDIRECT]) == 0) { |       if(xint(din.addrs[INDIRECT]) == 0) { | ||||||
| 	printf("allocate indirect block\n"); |         printf("allocate indirect block\n"); | ||||||
| 	din.addrs[INDIRECT] = xint(freeblock++); |         din.addrs[INDIRECT] = xint(freeblock++); | ||||||
| 	usedblocks++; |         usedblocks++; | ||||||
|       } |       } | ||||||
|       printf("read indirect block\n"); |       printf("read indirect block\n"); | ||||||
|       rsect(xint(din.addrs[INDIRECT]), (char *) indirect); |       rsect(xint(din.addrs[INDIRECT]), (char *) indirect); | ||||||
|       if (indirect[fbn - NDIRECT] == 0) { |       if (indirect[fbn - NDIRECT] == 0) { | ||||||
| 	indirect[fbn - NDIRECT] = xint(freeblock++); |         indirect[fbn - NDIRECT] = xint(freeblock++); | ||||||
| 	usedblocks++; |         usedblocks++; | ||||||
| 	wsect(xint(din.addrs[INDIRECT]), (char *) indirect); |         wsect(xint(din.addrs[INDIRECT]), (char *) indirect); | ||||||
|       } |       } | ||||||
|       x = xint(indirect[fbn-NDIRECT]); |       x = xint(indirect[fbn-NDIRECT]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
							
								
								
									
										236
									
								
								mmu.h
									
										
									
									
									
								
							
							
						
						
									
										236
									
								
								mmu.h
									
										
									
									
									
								
							|  | @ -3,133 +3,133 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| // Eflags register
 | // Eflags register
 | ||||||
| #define FL_CF		0x00000001	// Carry Flag
 | #define FL_CF           0x00000001      // Carry Flag
 | ||||||
| #define FL_PF		0x00000004	// Parity Flag
 | #define FL_PF           0x00000004      // Parity Flag
 | ||||||
| #define FL_AF		0x00000010	// Auxiliary carry Flag
 | #define FL_AF           0x00000010      // Auxiliary carry Flag
 | ||||||
| #define FL_ZF		0x00000040	// Zero Flag
 | #define FL_ZF           0x00000040      // Zero Flag
 | ||||||
| #define FL_SF		0x00000080	// Sign Flag
 | #define FL_SF           0x00000080      // Sign Flag
 | ||||||
| #define FL_TF		0x00000100	// Trap Flag
 | #define FL_TF           0x00000100      // Trap Flag
 | ||||||
| #define FL_IF		0x00000200	// Interrupt Flag
 | #define FL_IF           0x00000200      // Interrupt Flag
 | ||||||
| #define FL_DF		0x00000400	// Direction Flag
 | #define FL_DF           0x00000400      // Direction Flag
 | ||||||
| #define FL_OF		0x00000800	// Overflow Flag
 | #define FL_OF           0x00000800      // Overflow Flag
 | ||||||
| #define FL_IOPL_MASK	0x00003000	// I/O Privilege Level bitmask
 | #define FL_IOPL_MASK    0x00003000      // I/O Privilege Level bitmask
 | ||||||
| #define FL_IOPL_0	0x00000000	//   IOPL == 0
 | #define FL_IOPL_0       0x00000000      //   IOPL == 0
 | ||||||
| #define FL_IOPL_1	0x00001000	//   IOPL == 1
 | #define FL_IOPL_1       0x00001000      //   IOPL == 1
 | ||||||
| #define FL_IOPL_2	0x00002000	//   IOPL == 2
 | #define FL_IOPL_2       0x00002000      //   IOPL == 2
 | ||||||
| #define FL_IOPL_3	0x00003000	//   IOPL == 3
 | #define FL_IOPL_3       0x00003000      //   IOPL == 3
 | ||||||
| #define FL_NT		0x00004000	// Nested Task
 | #define FL_NT           0x00004000      // Nested Task
 | ||||||
| #define FL_RF		0x00010000	// Resume Flag
 | #define FL_RF           0x00010000      // Resume Flag
 | ||||||
| #define FL_VM		0x00020000	// Virtual 8086 mode
 | #define FL_VM           0x00020000      // Virtual 8086 mode
 | ||||||
| #define FL_AC		0x00040000	// Alignment Check
 | #define FL_AC           0x00040000      // Alignment Check
 | ||||||
| #define FL_VIF		0x00080000	// Virtual Interrupt Flag
 | #define FL_VIF          0x00080000      // Virtual Interrupt Flag
 | ||||||
| #define FL_VIP		0x00100000	// Virtual Interrupt Pending
 | #define FL_VIP          0x00100000      // Virtual Interrupt Pending
 | ||||||
| #define FL_ID		0x00200000	// ID flag
 | #define FL_ID           0x00200000      // ID flag
 | ||||||
| 
 | 
 | ||||||
| // Segment Descriptor
 | // Segment Descriptor
 | ||||||
| struct segdesc { | struct segdesc { | ||||||
| 	uint lim_15_0 : 16;  // Low bits of segment limit
 |   uint lim_15_0 : 16;  // Low bits of segment limit
 | ||||||
| 	uint base_15_0 : 16; // Low bits of segment base address
 |   uint base_15_0 : 16; // Low bits of segment base address
 | ||||||
| 	uint base_23_16 : 8; // Middle bits of segment base address
 |   uint base_23_16 : 8; // Middle bits of segment base address
 | ||||||
| 	uint type : 4;       // Segment type (see STS_ constants)
 |   uint type : 4;       // Segment type (see STS_ constants)
 | ||||||
| 	uint s : 1;          // 0 = system, 1 = application
 |   uint s : 1;          // 0 = system, 1 = application
 | ||||||
| 	uint dpl : 2;        // Descriptor Privilege Level
 |   uint dpl : 2;        // Descriptor Privilege Level
 | ||||||
| 	uint p : 1;          // Present
 |   uint p : 1;          // Present
 | ||||||
| 	uint lim_19_16 : 4;  // High bits of segment limit
 |   uint lim_19_16 : 4;  // High bits of segment limit
 | ||||||
| 	uint avl : 1;        // Unused (available for software use)
 |   uint avl : 1;        // Unused (available for software use)
 | ||||||
| 	uint rsv1 : 1;       // Reserved
 |   uint rsv1 : 1;       // Reserved
 | ||||||
| 	uint db : 1;         // 0 = 16-bit segment, 1 = 32-bit segment
 |   uint db : 1;         // 0 = 16-bit segment, 1 = 32-bit segment
 | ||||||
| 	uint g : 1;          // Granularity: limit scaled by 4K when set
 |   uint g : 1;          // Granularity: limit scaled by 4K when set
 | ||||||
| 	uint base_31_24 : 8; // High bits of segment base address
 |   uint base_31_24 : 8; // High bits of segment base address
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Null segment
 | // Null segment
 | ||||||
| #define SEG_NULL	(struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } | #define SEG_NULL        (struct segdesc){ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } | ||||||
| 
 | 
 | ||||||
| // Normal segment
 | // Normal segment
 | ||||||
| #define SEG(type, base, lim, dpl) (struct segdesc)			\ | #define SEG(type, base, lim, dpl) (struct segdesc)                      \ | ||||||
| { ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,	\ | { ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,       \ | ||||||
|     type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1,		\ |     type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1,            \ | ||||||
|     (uint) (base) >> 24 } |     (uint) (base) >> 24 } | ||||||
| 
 | 
 | ||||||
| #define SEG16(type, base, lim, dpl) (struct segdesc)			\ | #define SEG16(type, base, lim, dpl) (struct segdesc)                    \ | ||||||
| { (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,		\ | { (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,               \ | ||||||
|     type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0,		\ |     type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0,            \ | ||||||
|     (uint) (base) >> 24 } |     (uint) (base) >> 24 } | ||||||
| 
 | 
 | ||||||
| // Application segment type bits
 | // Application segment type bits
 | ||||||
| #define STA_X		0x8	    // Executable segment
 | #define STA_X           0x8         // Executable segment
 | ||||||
| #define STA_E		0x4	    // Expand down (non-executable segments)
 | #define STA_E           0x4         // Expand down (non-executable segments)
 | ||||||
| #define STA_C		0x4	    // Conforming code segment (executable only)
 | #define STA_C           0x4         // Conforming code segment (executable only)
 | ||||||
| #define STA_W		0x2	    // Writeable (non-executable segments)
 | #define STA_W           0x2         // Writeable (non-executable segments)
 | ||||||
| #define STA_R		0x2	    // Readable (executable segments)
 | #define STA_R           0x2         // Readable (executable segments)
 | ||||||
| #define STA_A		0x1	    // Accessed
 | #define STA_A           0x1         // Accessed
 | ||||||
| 
 | 
 | ||||||
| // System segment type bits
 | // System segment type bits
 | ||||||
| #define STS_T16A	0x1	    // Available 16-bit TSS
 | #define STS_T16A        0x1         // Available 16-bit TSS
 | ||||||
| #define STS_LDT		0x2	    // Local Descriptor Table
 | #define STS_LDT         0x2         // Local Descriptor Table
 | ||||||
| #define STS_T16B	0x3	    // Busy 16-bit TSS
 | #define STS_T16B        0x3         // Busy 16-bit TSS
 | ||||||
| #define STS_CG16	0x4	    // 16-bit Call Gate
 | #define STS_CG16        0x4         // 16-bit Call Gate
 | ||||||
| #define STS_TG		0x5	    // Task Gate / Coum Transmitions
 | #define STS_TG          0x5         // Task Gate / Coum Transmitions
 | ||||||
| #define STS_IG16	0x6	    // 16-bit Interrupt Gate
 | #define STS_IG16        0x6         // 16-bit Interrupt Gate
 | ||||||
| #define STS_TG16	0x7	    // 16-bit Trap Gate
 | #define STS_TG16        0x7         // 16-bit Trap Gate
 | ||||||
| #define STS_T32A	0x9	    // Available 32-bit TSS
 | #define STS_T32A        0x9         // Available 32-bit TSS
 | ||||||
| #define STS_T32B	0xB	    // Busy 32-bit TSS
 | #define STS_T32B        0xB         // Busy 32-bit TSS
 | ||||||
| #define STS_CG32	0xC	    // 32-bit Call Gate
 | #define STS_CG32        0xC         // 32-bit Call Gate
 | ||||||
| #define STS_IG32	0xE	    // 32-bit Interrupt Gate
 | #define STS_IG32        0xE         // 32-bit Interrupt Gate
 | ||||||
| #define STS_TG32	0xF	    // 32-bit Trap Gate
 | #define STS_TG32        0xF         // 32-bit Trap Gate
 | ||||||
| 
 | 
 | ||||||
| // Task state segment format
 | // Task state segment format
 | ||||||
| struct taskstate { | struct taskstate { | ||||||
| 	uint link;	// Old ts selector
 |   uint link;      // Old ts selector
 | ||||||
| 	uint esp0;	// Stack pointers and segment selectors
 |   uint esp0;      // Stack pointers and segment selectors
 | ||||||
| 	ushort ss0;	//   after an increase in privilege level
 |   ushort ss0;     //   after an increase in privilege level
 | ||||||
| 	ushort padding1; |   ushort padding1; | ||||||
| 	uint * esp1; |   uint * esp1; | ||||||
| 	ushort ss1; |   ushort ss1; | ||||||
| 	ushort padding2; |   ushort padding2; | ||||||
| 	uint * esp2; |   uint * esp2; | ||||||
| 	ushort ss2; |   ushort ss2; | ||||||
| 	ushort padding3; |   ushort padding3; | ||||||
| 	void * cr3;	// Page directory base
 |   void * cr3;     // Page directory base
 | ||||||
| 	uint * eip;	// Saved state from last task switch
 |   uint * eip;     // Saved state from last task switch
 | ||||||
| 	uint eflags; |   uint eflags; | ||||||
| 	uint eax;	// More saved state (registers)
 |   uint eax;       // More saved state (registers)
 | ||||||
| 	uint ecx; |   uint ecx; | ||||||
| 	uint edx; |   uint edx; | ||||||
| 	uint ebx; |   uint ebx; | ||||||
| 	uint * esp; |   uint * esp; | ||||||
| 	uint * ebp; |   uint * ebp; | ||||||
| 	uint esi; |   uint esi; | ||||||
| 	uint edi; |   uint edi; | ||||||
| 	ushort es;		// Even more saved state (segment selectors)
 |   ushort es;              // Even more saved state (segment selectors)
 | ||||||
| 	ushort padding4; |   ushort padding4; | ||||||
| 	ushort cs; |   ushort cs; | ||||||
| 	ushort padding5; |   ushort padding5; | ||||||
| 	ushort ss; |   ushort ss; | ||||||
| 	ushort padding6; |   ushort padding6; | ||||||
| 	ushort ds; |   ushort ds; | ||||||
| 	ushort padding7; |   ushort padding7; | ||||||
| 	ushort fs; |   ushort fs; | ||||||
| 	ushort padding8; |   ushort padding8; | ||||||
| 	ushort gs; |   ushort gs; | ||||||
| 	ushort padding9; |   ushort padding9; | ||||||
| 	ushort ldt; |   ushort ldt; | ||||||
| 	ushort padding10; |   ushort padding10; | ||||||
| 	ushort t;		// Trap on task switch
 |   ushort t;               // Trap on task switch
 | ||||||
| 	ushort iomb;	// I/O map base address
 |   ushort iomb;    // I/O map base address
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Gate descriptors for interrupts and traps
 | // Gate descriptors for interrupts and traps
 | ||||||
| struct gatedesc { | struct gatedesc { | ||||||
| 	uint off_15_0 : 16;   // low 16 bits of offset in segment
 |   uint off_15_0 : 16;   // low 16 bits of offset in segment
 | ||||||
| 	uint ss : 16;         // segment selector
 |   uint ss : 16;         // segment selector
 | ||||||
| 	uint args : 5;        // # args, 0 for interrupt/trap gates
 |   uint args : 5;        // # args, 0 for interrupt/trap gates
 | ||||||
| 	uint rsv1 : 3;        // reserved(should be zero I guess)
 |   uint rsv1 : 3;        // reserved(should be zero I guess)
 | ||||||
| 	uint type : 4;        // type(STS_{TG,IG32,TG32})
 |   uint type : 4;        // type(STS_{TG,IG32,TG32})
 | ||||||
| 	uint s : 1;           // must be 0 (system)
 |   uint s : 1;           // must be 0 (system)
 | ||||||
| 	uint dpl : 2;         // descriptor(meaning new) privilege level
 |   uint dpl : 2;         // descriptor(meaning new) privilege level
 | ||||||
| 	uint p : 1;           // Present
 |   uint p : 1;           // Present
 | ||||||
| 	uint off_31_16 : 16;  // high bits of offset in segment
 |   uint off_31_16 : 16;  // high bits of offset in segment
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Set up a normal interrupt/trap gate descriptor.
 | // Set up a normal interrupt/trap gate descriptor.
 | ||||||
|  | @ -138,18 +138,18 @@ struct gatedesc { | ||||||
| // - sel: Code segment selector for interrupt/trap handler
 | // - sel: Code segment selector for interrupt/trap handler
 | ||||||
| // - off: Offset in code segment for interrupt/trap handler
 | // - off: Offset in code segment for interrupt/trap handler
 | ||||||
| // - dpl: Descriptor Privilege Level -
 | // - dpl: Descriptor Privilege Level -
 | ||||||
| //	  the privilege level required for software to invoke
 | //        the privilege level required for software to invoke
 | ||||||
| //	  this interrupt/trap gate explicitly using an int instruction.
 | //        this interrupt/trap gate explicitly using an int instruction.
 | ||||||
| #define SETGATE(gate, istrap, sel, off, d)			\ | #define SETGATE(gate, istrap, sel, off, d)                      \ | ||||||
| {								\ | {                                                               \ | ||||||
| 	(gate).off_15_0 = (uint) (off) & 0xffff;		\ |   (gate).off_15_0 = (uint) (off) & 0xffff;                \ | ||||||
| 	(gate).ss = (sel);					\ |   (gate).ss = (sel);                                      \ | ||||||
| 	(gate).args = 0;					\ |   (gate).args = 0;                                        \ | ||||||
| 	(gate).rsv1 = 0;					\ |   (gate).rsv1 = 0;                                        \ | ||||||
| 	(gate).type = (istrap) ? STS_TG32 : STS_IG32;	\ |   (gate).type = (istrap) ? STS_TG32 : STS_IG32;   \ | ||||||
| 	(gate).s = 0;					\ |   (gate).s = 0;                                   \ | ||||||
| 	(gate).dpl = (d);					\ |   (gate).dpl = (d);                                       \ | ||||||
| 	(gate).p = 1;					\ |   (gate).p = 1;                                   \ | ||||||
| 	(gate).off_31_16 = (uint) (off) >> 16;		\ |   (gate).off_31_16 = (uint) (off) >> 16;          \ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										58
									
								
								mp.c
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								mp.c
									
										
									
									
									
								
							|  | @ -8,25 +8,25 @@ | ||||||
| #include "proc.h" | #include "proc.h" | ||||||
| 
 | 
 | ||||||
| static char* buses[] = { | static char* buses[] = { | ||||||
| 	"CBUSI ", |   "CBUSI ", | ||||||
| 	"CBUSII", |   "CBUSII", | ||||||
| 	"EISA  ", |   "EISA  ", | ||||||
| 	"FUTURE", |   "FUTURE", | ||||||
| 	"INTERN", |   "INTERN", | ||||||
| 	"ISA   ", |   "ISA   ", | ||||||
| 	"MBI   ", |   "MBI   ", | ||||||
| 	"MBII  ", |   "MBII  ", | ||||||
| 	"MCA   ", |   "MCA   ", | ||||||
| 	"MPI   ", |   "MPI   ", | ||||||
| 	"MPSA  ", |   "MPSA  ", | ||||||
| 	"NUBUS ", |   "NUBUS ", | ||||||
| 	"PCI   ", |   "PCI   ", | ||||||
| 	"PCMCIA", |   "PCMCIA", | ||||||
| 	"TC    ", |   "TC    ", | ||||||
| 	"VL    ", |   "VL    ", | ||||||
| 	"VME   ", |   "VME   ", | ||||||
| 	"XPRESS", |   "XPRESS", | ||||||
| 	0, |   0, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct cpu cpus[NCPU]; | struct cpu cpus[NCPU]; | ||||||
|  | @ -146,7 +146,7 @@ mp_init(void) | ||||||
|       proc = (struct mppe *) p; |       proc = (struct mppe *) p; | ||||||
|       cpus[ncpu].apicid = proc->apicid; |       cpus[ncpu].apicid = proc->apicid; | ||||||
|       if (proc->flags & MPBP) { |       if (proc->flags & MPBP) { | ||||||
| 	bcpu = &cpus[ncpu]; |         bcpu = &cpus[ncpu]; | ||||||
|       } |       } | ||||||
|       ncpu++; |       ncpu++; | ||||||
|       p += sizeof(struct mppe); |       p += sizeof(struct mppe); | ||||||
|  | @ -154,8 +154,8 @@ mp_init(void) | ||||||
|     case MPBUS: |     case MPBUS: | ||||||
|       bus = (struct mpbe *) p; |       bus = (struct mpbe *) p; | ||||||
|       for(i = 0; buses[i]; i++){ |       for(i = 0; buses[i]; i++){ | ||||||
| 	if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0) |         if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0) | ||||||
| 	  break; |           break; | ||||||
|       } |       } | ||||||
|       p += sizeof(struct mpbe); |       p += sizeof(struct mpbe); | ||||||
|       continue; |       continue; | ||||||
|  | @ -171,18 +171,18 @@ mp_init(void) | ||||||
|     default: |     default: | ||||||
|       cprintf("mpinit: unknown PCMP type 0x%x (e-p 0x%x)\n", *p, e-p); |       cprintf("mpinit: unknown PCMP type 0x%x (e-p 0x%x)\n", *p, e-p); | ||||||
|       while(p < e){ |       while(p < e){ | ||||||
| 	cprintf("%uX ", *p); |         cprintf("%uX ", *p); | ||||||
| 	p++; |         p++; | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   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 */ | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -205,7 +205,7 @@ mp_startthem(void) | ||||||
|   int c; |   int c; | ||||||
| 
 | 
 | ||||||
|   memmove((void *) APBOOTCODE,_binary_bootother_start,  |   memmove((void *) APBOOTCODE,_binary_bootother_start,  | ||||||
| 	  (uint) _binary_bootother_size); |           (uint) _binary_bootother_size); | ||||||
| 
 | 
 | ||||||
|   for(c = 0; c < ncpu; c++){ |   for(c = 0; c < ncpu; c++){ | ||||||
|     if (c == cpu()) continue; |     if (c == cpu()) continue; | ||||||
|  |  | ||||||
							
								
								
									
										170
									
								
								mp.h
									
										
									
									
									
								
							
							
						
						
									
										170
									
								
								mp.h
									
										
									
									
									
								
							|  | @ -3,121 +3,121 @@ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| 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 */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								picirq.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								picirq.c
									
										
									
									
									
								
							|  | @ -4,10 +4,10 @@ | ||||||
| #include "defs.h" | #include "defs.h" | ||||||
| 
 | 
 | ||||||
| // I/O Addresses of the two 8259A programmable interrupt controllers
 | // I/O Addresses of the two 8259A programmable interrupt controllers
 | ||||||
| #define IO_PIC1		0x20	// Master (IRQs 0-7)
 | #define IO_PIC1         0x20    // Master (IRQs 0-7)
 | ||||||
| #define IO_PIC2	        0xA0	// Slave (IRQs 8-15)
 | #define IO_PIC2         0xA0    // Slave (IRQs 8-15)
 | ||||||
| 
 | 
 | ||||||
| #define IRQ_SLAVE       2	// IRQ at which slave connects to master
 | #define IRQ_SLAVE       2       // IRQ at which slave connects to master
 | ||||||
| 
 | 
 | ||||||
| // Current IRQ mask.
 | // Current IRQ mask.
 | ||||||
| // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
 | // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
 | ||||||
|  | @ -49,19 +49,19 @@ pic_init(void) | ||||||
|   //    n:  1 = special fully nested mode
 |   //    n:  1 = special fully nested mode
 | ||||||
|   //    b:  1 = buffered mode
 |   //    b:  1 = buffered mode
 | ||||||
|   //    m:  0 = slave PIC, 1 = master PIC
 |   //    m:  0 = slave PIC, 1 = master PIC
 | ||||||
|   //	  (ignored when b is 0, as the master/slave role
 |   //      (ignored when b is 0, as the master/slave role
 | ||||||
|   //	  can be hardwired).
 |   //      can be hardwired).
 | ||||||
|   //    a:  1 = Automatic EOI mode
 |   //    a:  1 = Automatic EOI mode
 | ||||||
|   //    p:  0 = MCS-80/85 mode, 1 = intel x86 mode
 |   //    p:  0 = MCS-80/85 mode, 1 = intel x86 mode
 | ||||||
|   outb(IO_PIC1+1, 0x3); |   outb(IO_PIC1+1, 0x3); | ||||||
| 
 | 
 | ||||||
|   // Set up slave (8259A-2)
 |   // Set up slave (8259A-2)
 | ||||||
|   outb(IO_PIC2, 0x11);			// ICW1
 |   outb(IO_PIC2, 0x11);                  // ICW1
 | ||||||
|   outb(IO_PIC2+1, IRQ_OFFSET + 8);	// ICW2
 |   outb(IO_PIC2+1, IRQ_OFFSET + 8);      // ICW2
 | ||||||
|   outb(IO_PIC2+1, IRQ_SLAVE);		// ICW3
 |   outb(IO_PIC2+1, IRQ_SLAVE);           // ICW3
 | ||||||
|   // NB Automatic EOI mode doesn't tend to work on the slave.
 |   // NB Automatic EOI mode doesn't tend to work on the slave.
 | ||||||
|   // Linux source code says it's "to be investigated".
 |   // Linux source code says it's "to be investigated".
 | ||||||
|   outb(IO_PIC2+1, 0x3);			// ICW4
 |   outb(IO_PIC2+1, 0x3);                 // ICW4
 | ||||||
| 
 | 
 | ||||||
|   // OCW3:  0ef01prs
 |   // OCW3:  0ef01prs
 | ||||||
|   //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
 |   //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
 | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								printf.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								printf.c
									
										
									
									
									
								
							|  | @ -65,8 +65,8 @@ printf(int fd, char *fmt, ...) | ||||||
|           s++; |           s++; | ||||||
|         } |         } | ||||||
|       } else if(c == 'c'){ |       } else if(c == 'c'){ | ||||||
| 	putc(fd, *ap); |         putc(fd, *ap); | ||||||
| 	ap++; |         ap++; | ||||||
|       } else if(c == '%'){ |       } else if(c == '%'){ | ||||||
|         putc(fd, c); |         putc(fd, c); | ||||||
|       } else { |       } else { | ||||||
|  |  | ||||||
							
								
								
									
										58
									
								
								setjmp.S
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								setjmp.S
									
										
									
									
									
								
							|  | @ -1,37 +1,35 @@ | ||||||
| .globl setjmp
 | .globl setjmp
 | ||||||
| setjmp: | setjmp: | ||||||
| 	movl 4(%esp), %eax |   movl 4(%esp), %eax | ||||||
| 	 |    | ||||||
| 	movl %ebx, 0(%eax) |   movl %ebx, 0(%eax) | ||||||
| 	movl %ecx, 4(%eax) |   movl %ecx, 4(%eax) | ||||||
| 	movl %edx, 8(%eax) |   movl %edx, 8(%eax) | ||||||
| 	movl %esi, 12(%eax) |   movl %esi, 12(%eax) | ||||||
| 	movl %edi, 16(%eax) |   movl %edi, 16(%eax) | ||||||
| 	movl %esp, 20(%eax) |   movl %esp, 20(%eax) | ||||||
| 	movl %ebp, 24(%eax) |   movl %ebp, 24(%eax) | ||||||
| 	pushl 0(%esp)	/* %eip */ |   pushl 0(%esp)   /* %eip */ | ||||||
| 	popl 28(%eax) |   popl 28(%eax) | ||||||
| 	 |    | ||||||
| 	movl $0, %eax	/* return value */ |   movl $0, %eax   /* return value */ | ||||||
| 	ret |   ret | ||||||
| 
 | 
 | ||||||
| .globl longjmp
 | .globl longjmp
 | ||||||
| longjmp: | longjmp: | ||||||
| 	movl 4(%esp), %eax |   movl 4(%esp), %eax | ||||||
| 	 |    | ||||||
| 	movl 0(%eax), %ebx |   movl 0(%eax), %ebx | ||||||
| 	movl 4(%eax), %ecx |   movl 4(%eax), %ecx | ||||||
| 	movl 8(%eax), %edx |   movl 8(%eax), %edx | ||||||
| 	movl 12(%eax), %esi |   movl 12(%eax), %esi | ||||||
| 	movl 16(%eax), %edi |   movl 16(%eax), %edi | ||||||
| 	movl 20(%eax), %esp |   movl 20(%eax), %esp | ||||||
| 	movl 24(%eax), %ebp |   movl 24(%eax), %ebp | ||||||
| 
 | 
 | ||||||
| 	addl $4, %esp	/* pop %eip into thin air */ |   addl $4, %esp   /* pop %eip into thin air */ | ||||||
| 	pushl 28(%eax)	/* push new %eip */ |   pushl 28(%eax)  /* push new %eip */ | ||||||
| 	 |    | ||||||
| 	movl $1, %eax	/* return value (appears to come from setjmp!) */ |   movl $1, %eax   /* return value (appears to come from setjmp!) */ | ||||||
| 	ret |   ret | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	 |  | ||||||
|  |  | ||||||
							
								
								
									
										124
									
								
								sh.c
									
										
									
									
									
								
							
							
						
						
									
										124
									
								
								sh.c
									
										
									
									
									
								
							|  | @ -68,28 +68,28 @@ parse(char *s) | ||||||
|   while (1) { |   while (1) { | ||||||
|     switch ((c = gettoken(0, &t))) { |     switch ((c = gettoken(0, &t))) { | ||||||
| 
 | 
 | ||||||
|     case 'w':	// Add an argument
 |     case 'w':   // Add an argument
 | ||||||
|       if (cmdlist[nextcmd].argc >= MAXARGS) { |       if (cmdlist[nextcmd].argc >= MAXARGS) { | ||||||
| 	printf(2, "too many arguments\n"); |         printf(2, "too many arguments\n"); | ||||||
| 	return -1; |         return -1; | ||||||
|       } |       } | ||||||
|       cmdlist[nextcmd].argv[cmdlist[nextcmd].argc++] = t; |       cmdlist[nextcmd].argv[cmdlist[nextcmd].argc++] = t; | ||||||
|       break; |       break; | ||||||
| 			 |                          | ||||||
|     case '<':	// Input redirection
 |     case '<':   // Input redirection
 | ||||||
|       // Grab the filename from the argument list
 |       // Grab the filename from the argument list
 | ||||||
|       if (gettoken(0, &t) != 'w') { |       if (gettoken(0, &t) != 'w') { | ||||||
| 	printf(2, "syntax error: < not followed by word\n"); |         printf(2, "syntax error: < not followed by word\n"); | ||||||
| 	return -1; |         return -1; | ||||||
|       } |       } | ||||||
|       addio('<', t); |       addio('<', t); | ||||||
|       break; |       break; | ||||||
| 			 |                          | ||||||
|     case '>':	// Output redirection
 |     case '>':   // Output redirection
 | ||||||
|       // Grab the filename from the argument list
 |       // Grab the filename from the argument list
 | ||||||
|       if (gettoken(0, &t) != 'w') { |       if (gettoken(0, &t) != 'w') { | ||||||
| 	printf(2, "syntax error: > not followed by word\n"); |         printf(2, "syntax error: > not followed by word\n"); | ||||||
| 	return -1; |         return -1; | ||||||
|       } |       } | ||||||
|       addio('>', t); |       addio('>', t); | ||||||
|       break; |       break; | ||||||
|  | @ -100,13 +100,13 @@ parse(char *s) | ||||||
|       nextcmd++; |       nextcmd++; | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|     case 0:		// String is complete
 |     case 0:             // String is complete
 | ||||||
|       return 0; |       return 0; | ||||||
| 			 |                          | ||||||
|     default: |     default: | ||||||
|       printf(2, "syntax error: bad return %d from gettoken", c); |       printf(2, "syntax error: bad return %d from gettoken", c); | ||||||
|       return -1; |       return -1; | ||||||
| 			 |                          | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -136,14 +136,14 @@ runcmd(void) | ||||||
|       cmdlist[c].argv[0] = cmdlist[c].argv0buf; |       cmdlist[c].argv[0] = cmdlist[c].argv0buf; | ||||||
|     } |     } | ||||||
|     cmdlist[c].argv[cmdlist[c].argc] = 0; |     cmdlist[c].argv[cmdlist[c].argc] = 0; | ||||||
| 	 |          | ||||||
|     // Print the command.
 |     // Print the command.
 | ||||||
|     if (debug) { |     if (debug) { | ||||||
|       printf(2, "[%d] SPAWN:", getpid()); |       printf(2, "[%d] SPAWN:", getpid()); | ||||||
|       for (i = 0; cmdlist[c].argv[i]; i++) |       for (i = 0; cmdlist[c].argv[i]; i++) | ||||||
| 	printf(2, " %s", cmdlist[c].argv[i]); |         printf(2, " %s", cmdlist[c].argv[i]); | ||||||
|       for (i = 0; i < nextio; i++) { |       for (i = 0; i < nextio; i++) { | ||||||
| 	printf(2, "%c %s", iolist[i].token, iolist[i].s); |         printf(2, "%c %s", iolist[i].token, iolist[i].s); | ||||||
|       } |       } | ||||||
|       printf(2, "\n"); |       printf(2, "\n"); | ||||||
|     } |     } | ||||||
|  | @ -156,55 +156,55 @@ runcmd(void) | ||||||
| 
 | 
 | ||||||
|     if (cmdlist[c].token == '|') |     if (cmdlist[c].token == '|') | ||||||
|       if (pipe(fdarray) < 0) |       if (pipe(fdarray) < 0) | ||||||
| 	printf(2, "cmd %d pipe failed\n", c); |         printf(2, "cmd %d pipe failed\n", c); | ||||||
| 
 | 
 | ||||||
|     pid = fork(); |     pid = fork(); | ||||||
|     if (pid == 0) { |     if (pid == 0) { | ||||||
|       if (cmdlist[c].token == '|') { |       if (cmdlist[c].token == '|') { | ||||||
| 	if (close(1) < 0)  |         if (close(1) < 0)  | ||||||
| 	  printf(2, "close 1 failed\n"); |           printf(2, "close 1 failed\n"); | ||||||
| 	if ((tfd = dup(fdarray[1])) < 0) |         if ((tfd = dup(fdarray[1])) < 0) | ||||||
| 	  printf(2, "dup failed\n"); |           printf(2, "dup failed\n"); | ||||||
| 	if (close(fdarray[0]) < 0) |         if (close(fdarray[0]) < 0) | ||||||
| 	  printf(2, "close fdarray[0] failed\n"); |           printf(2, "close fdarray[0] failed\n"); | ||||||
| 	if (close(fdarray[1]) < 0) |         if (close(fdarray[1]) < 0) | ||||||
| 	  printf(2, "close fdarray[1] failed\n"); |           printf(2, "close fdarray[1] failed\n"); | ||||||
|       } |       } | ||||||
|       if (c > 0 && cmdlist[c-1].token == '|') { |       if (c > 0 && cmdlist[c-1].token == '|') { | ||||||
| 	if (close(0) < 0)  |         if (close(0) < 0)  | ||||||
| 	  printf(2, "close 0 failed\n"); |           printf(2, "close 0 failed\n"); | ||||||
| 	if ((tfd = dup(fdarray[0])) < 0) |         if ((tfd = dup(fdarray[0])) < 0) | ||||||
| 	  printf(2, "dup failed\n"); |           printf(2, "dup failed\n"); | ||||||
| 	if (close(fdarray[0]) < 0) |         if (close(fdarray[0]) < 0) | ||||||
| 	  printf(2, "close fdarray[0] failed\n"); |           printf(2, "close fdarray[0] failed\n"); | ||||||
| 	if (close(fdarray[1]) < 0) |         if (close(fdarray[1]) < 0) | ||||||
| 	  printf(2, "close fdarray[1] failed\n"); |           printf(2, "close fdarray[1] failed\n"); | ||||||
|       } |       } | ||||||
|       if (ioredirection() < 0) |       if (ioredirection() < 0) | ||||||
| 	exit(); |         exit(); | ||||||
|       if ((r = exec(cmdlist[c].argv0buf, (char**) cmdlist[c].argv)) < 0) { |       if ((r = exec(cmdlist[c].argv0buf, (char**) cmdlist[c].argv)) < 0) { | ||||||
| 	printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r); |         printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r); | ||||||
| 	exit(); |         exit(); | ||||||
|       } |       } | ||||||
|     } else if (pid > 0) { |     } else if (pid > 0) { | ||||||
|       int p; |       int p; | ||||||
|       if (debug) |       if (debug) | ||||||
| 	printf(2, "[%d] FORKED child %d\n", getpid(), pid); |         printf(2, "[%d] FORKED child %d\n", getpid(), pid); | ||||||
| 
 | 
 | ||||||
|       if (c > 0 && cmdlist[c-1].token == '|') { |       if (c > 0 && cmdlist[c-1].token == '|') { | ||||||
| 	close(fdarray[0]); |         close(fdarray[0]); | ||||||
| 	close(fdarray[1]); |         close(fdarray[1]); | ||||||
|       } |       } | ||||||
|       if (cmdlist[c].token != '|') { |       if (cmdlist[c].token != '|') { | ||||||
| 	if (debug) |         if (debug) | ||||||
| 	  printf(2, "[%d] WAIT for children\n", getpid()); |           printf(2, "[%d] WAIT for children\n", getpid()); | ||||||
| 	do { |         do { | ||||||
| 	  p = wait(); |           p = wait(); | ||||||
| 	  if (debug) |           if (debug) | ||||||
| 	    printf(2, "[%d] WAIT child %d finished\n", getpid(), p); |             printf(2, "[%d] WAIT child %d finished\n", getpid(), p); | ||||||
| 	} while (p > 0); |         } while (p > 0); | ||||||
| 	if (debug) |         if (debug) | ||||||
| 	  printf(2, "[%d] wait finished\n", getpid()); |           printf(2, "[%d] wait finished\n", getpid()); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -219,23 +219,23 @@ ioredirection(void) | ||||||
|     switch (iolist[i].token) { |     switch (iolist[i].token) { | ||||||
|     case '<': |     case '<': | ||||||
|       if (close(0) < 0) |       if (close(0) < 0) | ||||||
| 	printf(2, "close 0 failed\n"); |         printf(2, "close 0 failed\n"); | ||||||
|       if ((fd = open(iolist[i].s, O_RDONLY)) < 0) { |       if ((fd = open(iolist[i].s, O_RDONLY)) < 0) { | ||||||
| 	printf(2, "failed to open %s for read: %d", iolist[i].s, fd); |         printf(2, "failed to open %s for read: %d", iolist[i].s, fd); | ||||||
| 	return -1; |         return -1; | ||||||
|       } |       } | ||||||
|       if (debug) |       if (debug) | ||||||
| 	printf(2, "redirect 0 from %s\n", iolist[i].s); |         printf(2, "redirect 0 from %s\n", iolist[i].s); | ||||||
|       break; |       break; | ||||||
|     case '>': |     case '>': | ||||||
|       if (close(1) < 0) |       if (close(1) < 0) | ||||||
| 	printf(2, "close 1 failed\n"); |         printf(2, "close 1 failed\n"); | ||||||
|       if ((fd = open(iolist[i].s, O_WRONLY|O_CREATE)) < 0) { |       if ((fd = open(iolist[i].s, O_WRONLY|O_CREATE)) < 0) { | ||||||
| 	printf(2, "failed to open %s for write: %d", iolist[i].s, fd); |         printf(2, "failed to open %s for write: %d", iolist[i].s, fd); | ||||||
| 	exit(); |         exit(); | ||||||
|       } |       } | ||||||
|       if (debug) |       if (debug) | ||||||
| 	printf(2, "redirect 1 to %s\n", iolist[i].s); |         printf(2, "redirect 1 to %s\n", iolist[i].s); | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -283,11 +283,11 @@ gettoken(char *s, char **p1) | ||||||
| // Get the next token from string s.
 | // Get the next token from string s.
 | ||||||
| // Set *p1 to the beginning of the token and *p2 just past the token.
 | // Set *p1 to the beginning of the token and *p2 just past the token.
 | ||||||
| // Returns
 | // Returns
 | ||||||
| //	0 for end-of-string;
 | //      0 for end-of-string;
 | ||||||
| //	< for <;
 | //      < for <;
 | ||||||
| //	> for >;
 | //      > for >;
 | ||||||
| //	| for |;
 | //      | for |;
 | ||||||
| //	w for a word.
 | //      w for a word.
 | ||||||
| //
 | //
 | ||||||
| // Eventually (once we parse the space where the \0 will go),
 | // Eventually (once we parse the space where the \0 will go),
 | ||||||
| // words get nul-terminated.
 | // words get nul-terminated.
 | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								sign.pl
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								sign.pl
									
										
									
									
									
								
							|  | @ -5,8 +5,8 @@ open(SIG, $ARGV[0]) || die "open $ARGV[0]: $!"; | ||||||
| $n = sysread(SIG, $buf, 1000); | $n = sysread(SIG, $buf, 1000); | ||||||
| 
 | 
 | ||||||
| if($n > 510){ | if($n > 510){ | ||||||
| 	print STDERR "boot block too large: $n bytes (max 510)\n"; |   print STDERR "boot block too large: $n bytes (max 510)\n"; | ||||||
| 	exit 1; |   exit 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| print STDERR "boot block is $n bytes (max 510)\n"; | print STDERR "boot block is $n bytes (max 510)\n"; | ||||||
|  |  | ||||||
|  | @ -40,7 +40,7 @@ acquire(struct spinlock * lock) | ||||||
|                  |                  | ||||||
|   while(cmpxchg(0, 1, &lock->locked) == 1) |   while(cmpxchg(0, 1, &lock->locked) == 1) | ||||||
|     ; |     ; | ||||||
|   cpuid(0, 0, 0, 0, 0);	// memory barrier
 |   cpuid(0, 0, 0, 0, 0);  // memory barrier
 | ||||||
|   getcallerpcs(&lock, lock->pcs); |   getcallerpcs(&lock, lock->pcs); | ||||||
|   lock->cpu = cpu() + 10; |   lock->cpu = cpu() + 10; | ||||||
| } | } | ||||||
|  | @ -54,7 +54,7 @@ release(struct spinlock * lock) | ||||||
| 
 | 
 | ||||||
|   lock->pcs[0] = 0; |   lock->pcs[0] = 0; | ||||||
|   lock->cpu = 0xffffffff; |   lock->cpu = 0xffffffff; | ||||||
|   cpuid(0, 0, 0, 0, 0);	// memory barrier
 |   cpuid(0, 0, 0, 0, 0);  // memory barrier
 | ||||||
|   lock->locked = 0; |   lock->locked = 0; | ||||||
|   if(--cpus[cpu()].nlock == 0) |   if(--cpus[cpu()].nlock == 0) | ||||||
|     sti(); |     sti(); | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								string.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								string.c
									
										
									
									
									
								
							|  | @ -32,7 +32,7 @@ memmove(void *dst, const void *src, uint n) | ||||||
| { | { | ||||||
|   const char *s; |   const char *s; | ||||||
|   char *d; |   char *d; | ||||||
| 	 | 
 | ||||||
|   s = src; |   s = src; | ||||||
|   d = dst; |   d = dst; | ||||||
|   if (s < d && s + n > d) { |   if (s < d && s + n > d) { | ||||||
|  | @ -50,10 +50,10 @@ memmove(void *dst, const void *src, uint n) | ||||||
| int | int | ||||||
| strncmp(const char *p, const char *q, uint n) | strncmp(const char *p, const char *q, uint n) | ||||||
| { | { | ||||||
| 	while (n > 0 && *p && *p == *q) |   while (n > 0 && *p && *p == *q) | ||||||
| 		n--, p++, q++; |     n--, p++, q++; | ||||||
| 	if (n == 0) |   if (n == 0) | ||||||
| 		return 0; |     return 0; | ||||||
| 	else |   else | ||||||
| 		return (int) ((uchar) *p - (uchar) *q); |     return (int) ((uchar) *p - (uchar) *q); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								trap.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								trap.c
									
										
									
									
									
								
							|  | @ -86,7 +86,7 @@ trap(struct trapframe *tf) | ||||||
| 
 | 
 | ||||||
|   if(curproc[cpu()]) { |   if(curproc[cpu()]) { | ||||||
|     cprintf("pid %d: unhandled trap %d on cpu %d eip %x---terminate process\n",  |     cprintf("pid %d: unhandled trap %d on cpu %d eip %x---terminate process\n",  | ||||||
| 	    curproc[cpu()]->pid, v, cpu(), tf->eip); |             curproc[cpu()]->pid, v, cpu(), tf->eip); | ||||||
|     proc_exit(); |     proc_exit(); | ||||||
|   } |   } | ||||||
|   cprintf("unexpected trap %d from cpu %d eip %x\n", v, cpu(), tf->eip); |   cprintf("unexpected trap %d from cpu %d eip %x\n", v, cpu(), tf->eip); | ||||||
|  |  | ||||||
							
								
								
									
										54
									
								
								trapasm.S
									
										
									
									
									
								
							
							
						
						
									
										54
									
								
								trapasm.S
									
										
									
									
									
								
							|  | @ -1,38 +1,38 @@ | ||||||
| 	.text | .text | ||||||
| .globl trap
 | .globl trap
 | ||||||
| .globl trapret1
 | .globl trapret1
 | ||||||
| 
 | 
 | ||||||
| .globl alltraps
 | .globl alltraps
 | ||||||
| alltraps: | alltraps: | ||||||
|         /* vectors.S sends all traps here */ |   /* vectors.S sends all traps here */ | ||||||
|         pushl   %ds     # build |   pushl   %ds      # build | ||||||
|         pushl   %es     #  trap |   pushl   %es      #  trap | ||||||
|         pushal          #  frame |   pushal           #  frame | ||||||
|         movl $16,%eax    # SEG_KDATA << 3 |   movl $16,%eax    # SEG_KDATA << 3 | ||||||
|         movw %ax,%ds        #  kernel |   movw %ax,%ds     #  kernel | ||||||
|         movw %ax,%es        #  segments |   movw %ax,%es     #  segments | ||||||
|         pushl %esp      # pass pointer to this trapframe |   pushl %esp       # pass pointer to this trapframe | ||||||
|         call    trap        #  and call trap() |   call    trap     #  and call trap() | ||||||
|         addl $4, %esp |   addl $4, %esp | ||||||
|         # return falls through to trapret... |   # return falls through to trapret... | ||||||
|          |    | ||||||
| 	/* |   /* | ||||||
|          * a forked process RETs here |    * a forked process RETs here | ||||||
|          * expects ESP to point to a Trapframe |    * expects ESP to point to a Trapframe | ||||||
|          */ |    */ | ||||||
| .globl trapret
 | .globl trapret
 | ||||||
| trapret: | trapret: | ||||||
|         popal |   popal | ||||||
|         popl %es |   popl %es | ||||||
|         popl %ds |   popl %ds | ||||||
|         addl $0x8, %esp /* trapno and errcode */ |   addl $0x8, %esp /* trapno and errcode */ | ||||||
|         iret |   iret | ||||||
| 
 | 
 | ||||||
| .globl forkret1
 | .globl forkret1
 | ||||||
| forkret1: | forkret1: | ||||||
| 	movl 4(%esp), %esp |   movl 4(%esp), %esp | ||||||
| 	jmp trapret |   jmp trapret | ||||||
| 		 |            | ||||||
| .globl 	acpu
 | .globl  acpu
 | ||||||
| acpu: | acpu: | ||||||
| 	.long 0
 |   .long 0
 | ||||||
|  |  | ||||||
							
								
								
									
										48
									
								
								traps.h
									
										
									
									
									
								
							
							
						
						
									
										48
									
								
								traps.h
									
										
									
									
									
								
							|  | @ -1,33 +1,33 @@ | ||||||
| // system defined:
 | // system defined:
 | ||||||
| #define T_DIVIDE     0		// divide error
 | #define T_DIVIDE         0          // divide error
 | ||||||
| #define T_DEBUG      1		// debug exception
 | #define T_DEBUG          1          // debug exception
 | ||||||
| #define T_NMI        2		// non-maskable interrupt
 | #define T_NMI            2          // non-maskable interrupt
 | ||||||
| #define T_BRKPT      3		// breakpoint
 | #define T_BRKPT          3          // breakpoint
 | ||||||
| #define T_OFLOW      4		// overflow
 | #define T_OFLOW          4          // overflow
 | ||||||
| #define T_BOUND      5		// bounds check
 | #define T_BOUND          5          // bounds check
 | ||||||
| #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
 | ||||||
| #define T_SIMDERR   19		// SIMD floating point error
 | #define T_SIMDERR       19          // SIMD floating point error
 | ||||||
| 
 | 
 | ||||||
| // These are arbitrarily chosen, but with care not to overlap
 | // These are arbitrarily chosen, but with care not to overlap
 | ||||||
| // processor defined exceptions or interrupt vectors.
 | // processor defined exceptions or interrupt vectors.
 | ||||||
| #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 | ||||||
| #define IRQ_TIMER       18 | #define IRQ_TIMER       18 | ||||||
| #define IRQ_ERROR       19 | #define IRQ_ERROR       19 | ||||||
|  |  | ||||||
							
								
								
									
										32
									
								
								ulib.c
									
										
									
									
									
								
							
							
						
						
									
										32
									
								
								ulib.c
									
										
									
									
									
								
							|  | @ -12,20 +12,20 @@ puts(char *s) | ||||||
| char* | char* | ||||||
| strcpy(char *s, char *t) | strcpy(char *s, char *t) | ||||||
| { | { | ||||||
| 	char *os; |   char *os; | ||||||
| 	 |    | ||||||
| 	os = s; |   os = s; | ||||||
| 	while((*s++ = *t++) != 0) |   while((*s++ = *t++) != 0) | ||||||
| 		; |     ; | ||||||
| 	return os; |   return os; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
| strcmp(const char *p, const char *q) | strcmp(const char *p, const char *q) | ||||||
| { | { | ||||||
| 	while (*p && *p == *q) |   while (*p && *p == *q) | ||||||
| 		p++, q++; |     p++, q++; | ||||||
| 	return (int) ((unsigned char) *p - (unsigned char) *q); |   return (int) ((unsigned char) *p - (unsigned char) *q); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsigned int | unsigned int | ||||||
|  | @ -37,7 +37,7 @@ strlen(char *s) | ||||||
|   return n; |   return n; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void * | void* | ||||||
| memset(void *dst, int c, unsigned int n) | memset(void *dst, int c, unsigned int n) | ||||||
| { | { | ||||||
|   char *d = (char *) dst; |   char *d = (char *) dst; | ||||||
|  | @ -48,16 +48,16 @@ memset(void *dst, int c, unsigned int n) | ||||||
|   return dst; |   return dst; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| char * | char* | ||||||
| strchr(const char *s, char c) | strchr(const char *s, char c) | ||||||
| { | { | ||||||
| 	for (; *s; s++) |   for (; *s; s++) | ||||||
| 		if (*s == c) |     if (*s == c) | ||||||
| 			return (char *) s; |       return (char *) s; | ||||||
| 	return 0; |   return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| char * | char* | ||||||
| gets(char *buf, int max) | gets(char *buf, int max) | ||||||
| { | { | ||||||
|   int i = 0, cc; |   int i = 0, cc; | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								umalloc.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								umalloc.c
									
										
									
									
									
								
							|  | @ -74,17 +74,17 @@ malloc(uint nbytes) | ||||||
|   for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) { |   for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) { | ||||||
|     if (p->s.size >= nunits) { |     if (p->s.size >= nunits) { | ||||||
|       if (p->s.size == nunits) |       if (p->s.size == nunits) | ||||||
| 	prevp->s.ptr = p->s.ptr; |         prevp->s.ptr = p->s.ptr; | ||||||
|       else { |       else { | ||||||
| 	p->s.size -= nunits; |         p->s.size -= nunits; | ||||||
| 	p += p->s.size; |         p += p->s.size; | ||||||
| 	p->s.size = nunits; |         p->s.size = nunits; | ||||||
|       } |       } | ||||||
|       freep = prevp; |       freep = prevp; | ||||||
|       return (void *) (p + 1); |       return (void *) (p + 1); | ||||||
|     } |     } | ||||||
|     if (p == freep)  |     if (p == freep)  | ||||||
|       if ((p = morecore(nunits)) == 0) |       if ((p = morecore(nunits)) == 0) | ||||||
| 	return 0; |         return 0; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								userfs.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								userfs.c
									
										
									
									
									
								
							|  | @ -115,8 +115,8 @@ writetest1(void) | ||||||
|     i = read(fd, buf, 512); |     i = read(fd, buf, 512); | ||||||
|     if (i == 0) { |     if (i == 0) { | ||||||
|       if (n == MAXFILE - 1) { |       if (n == MAXFILE - 1) { | ||||||
| 	printf(stdout, "read only %d blocks from big", n); |         printf(stdout, "read only %d blocks from big", n); | ||||||
| 	exit(); |         exit(); | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|     } else if (i != 512) { |     } else if (i != 512) { | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								usys.S
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								usys.S
									
										
									
									
									
								
							|  | @ -2,11 +2,11 @@ | ||||||
| #include "traps.h" | #include "traps.h" | ||||||
| 
 | 
 | ||||||
| #define STUB(name) \ | #define STUB(name) \ | ||||||
| 	.globl name; \
 |   .globl name; \
 | ||||||
| 	name: \ |   name: \ | ||||||
| 		movl $SYS_ ## name, %eax; \ |     movl $SYS_ ## name, %eax; \ | ||||||
| 		int $T_SYSCALL; \
 |     int $T_SYSCALL; \
 | ||||||
| 		ret  |     ret  | ||||||
| 
 | 
 | ||||||
| STUB(fork) | STUB(fork) | ||||||
| STUB(exit) | STUB(exit) | ||||||
|  |  | ||||||
|  | @ -13,10 +13,10 @@ for(my $i = 0; $i < 256; $i++){ | ||||||
|     print ".globl vector$i\n"; |     print ".globl vector$i\n"; | ||||||
|     print "vector$i:\n"; |     print "vector$i:\n"; | ||||||
|     if(($i < 8 || $i > 14) && $i != 17){ |     if(($i < 8 || $i > 14) && $i != 17){ | ||||||
|         print "\tpushl \$0\n"; |         print "  pushl \$0\n"; | ||||||
|     } |     } | ||||||
|     print "\tpushl \$$i\n"; |     print "  pushl \$$i\n"; | ||||||
|     print "\tjmp alltraps\n"; |     print "  jmp alltraps\n"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| print "\n/* vector table */\n"; | print "\n/* vector table */\n"; | ||||||
|  | @ -24,5 +24,5 @@ print ".data\n"; | ||||||
| print ".globl vectors\n"; | print ".globl vectors\n"; | ||||||
| print "vectors:\n"; | print "vectors:\n"; | ||||||
| for(my $i = 0; $i < 256; $i++){ | for(my $i = 0; $i < 256; $i++){ | ||||||
|     print "\t.long vector$i\n"; |     print "  .long vector$i\n"; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										142
									
								
								x86.h
									
										
									
									
									
								
							
							
						
						
									
										142
									
								
								x86.h
									
										
									
									
									
								
							|  | @ -1,39 +1,39 @@ | ||||||
| static __inline uchar | static __inline uchar | ||||||
| inb(int port) | inb(int port) | ||||||
| { | { | ||||||
| 	uchar data; |   uchar data; | ||||||
| 	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port)); |   __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port)); | ||||||
| 	return data; |   return data; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| insl(int port, void *addr, int cnt) | insl(int port, void *addr, int cnt) | ||||||
| { | { | ||||||
| 	__asm __volatile("cld\n\trepne\n\tinsl"			: |   __asm __volatile("cld\n\trepne\n\tinsl"     : | ||||||
| 			 "=D" (addr), "=c" (cnt)		: |                    "=D" (addr), "=c" (cnt)    : | ||||||
| 			 "d" (port), "0" (addr), "1" (cnt)	: |                    "d" (port), "0" (addr), "1" (cnt)  : | ||||||
| 			 "memory", "cc"); |                    "memory", "cc"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| outb(int port, uchar data) | outb(int port, uchar data) | ||||||
| { | { | ||||||
| 	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port)); |   __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| outw(int port, ushort data) | outw(int port, ushort data) | ||||||
| { | { | ||||||
| 	__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port)); |   __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| outsl(int port, const void *addr, int cnt) | outsl(int port, const void *addr, int cnt) | ||||||
| { | { | ||||||
| 	__asm __volatile("cld\n\trepne\n\toutsl"		: |   __asm __volatile("cld\n\trepne\n\toutsl"    : | ||||||
| 			 "=S" (addr), "=c" (cnt)		: |                    "=S" (addr), "=c" (cnt)    : | ||||||
| 			 "d" (port), "0" (addr), "1" (cnt)	: |                    "d" (port), "0" (addr), "1" (cnt)  : | ||||||
| 			 "cc"); |                    "cc"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct segdesc; | struct segdesc; | ||||||
|  | @ -41,13 +41,13 @@ struct segdesc; | ||||||
| static __inline void | static __inline void | ||||||
| lgdt(struct segdesc *p, int size) | lgdt(struct segdesc *p, int size) | ||||||
| { | { | ||||||
| 	volatile ushort pd[3]; |   volatile ushort pd[3]; | ||||||
|    |    | ||||||
| 	pd[0] = size-1; |   pd[0] = size-1; | ||||||
| 	pd[1] = (uint)p; |   pd[1] = (uint)p; | ||||||
| 	pd[2] = (uint)p >> 16; |   pd[2] = (uint)p >> 16; | ||||||
| 
 | 
 | ||||||
| 	asm volatile("lgdt (%0)" : : "g" (pd)); |   asm volatile("lgdt (%0)" : : "g" (pd)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct gatedesc; | struct gatedesc; | ||||||
|  | @ -55,99 +55,99 @@ struct gatedesc; | ||||||
| static __inline void | static __inline void | ||||||
| lidt(struct gatedesc *p, int size) | lidt(struct gatedesc *p, int size) | ||||||
| { | { | ||||||
| 	volatile ushort pd[3]; |   volatile ushort pd[3]; | ||||||
|    |    | ||||||
| 	pd[0] = size-1; |   pd[0] = size-1; | ||||||
| 	pd[1] = (uint)p; |   pd[1] = (uint)p; | ||||||
| 	pd[2] = (uint)p >> 16; |   pd[2] = (uint)p >> 16; | ||||||
|    |    | ||||||
| 	asm volatile("lidt (%0)" : : "g" (pd)); |   asm volatile("lidt (%0)" : : "g" (pd)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| ltr(ushort sel) | ltr(ushort sel) | ||||||
| { | { | ||||||
| 	__asm __volatile("ltr %0" : : "r" (sel)); |   __asm __volatile("ltr %0" : : "r" (sel)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline uint | static __inline uint | ||||||
| read_eflags(void) | read_eflags(void) | ||||||
| { | { | ||||||
|         uint eflags; |   uint eflags; | ||||||
|         __asm __volatile("pushfl; popl %0" : "=r" (eflags)); |   __asm __volatile("pushfl; popl %0" : "=r" (eflags)); | ||||||
|         return eflags; |   return eflags; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| write_eflags(uint eflags) | write_eflags(uint eflags) | ||||||
| { | { | ||||||
|         __asm __volatile("pushl %0; popfl" : : "r" (eflags)); |   __asm __volatile("pushl %0; popfl" : : "r" (eflags)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp) | cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp) | ||||||
| { | { | ||||||
| 	uint eax, ebx, ecx, edx; |   uint eax, ebx, ecx, edx; | ||||||
| 	asm volatile("cpuid"  |   asm volatile("cpuid" : | ||||||
| 		: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) |                "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : | ||||||
| 		: "a" (info)); |                "a" (info)); | ||||||
| 	if (eaxp) |   if (eaxp) | ||||||
| 		*eaxp = eax; |     *eaxp = eax; | ||||||
| 	if (ebxp) |   if (ebxp) | ||||||
| 		*ebxp = ebx; |     *ebxp = ebx; | ||||||
| 	if (ecxp) |   if (ecxp) | ||||||
| 		*ecxp = ecx; |     *ecxp = ecx; | ||||||
| 	if (edxp) |   if (edxp) | ||||||
| 		*edxp = edx; |     *edxp = edx; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline uint | static __inline uint | ||||||
| cmpxchg(uint oldval, uint newval, volatile uint* lock_addr) | cmpxchg(uint oldval, uint newval, volatile uint* lock_addr) | ||||||
| { | { | ||||||
|   uint result; |   uint result; | ||||||
|   __asm__ __volatile__( |   __asm__ __volatile__("lock; cmpxchgl %2, %0" : | ||||||
| 		       "lock; cmpxchgl %2, %0" |                        "+m" (*lock_addr), "=a" (result) : | ||||||
| 		       :"+m" (*lock_addr), "=a" (result) : "r"(newval), "1"(oldval) : "cc" |                        "r"(newval), "1"(oldval) : | ||||||
| 		       ); |                        "cc"); | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| cli(void) | cli(void) | ||||||
| { | { | ||||||
| 	__asm__ volatile("cli"); |   __asm__ volatile("cli"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline void | static __inline void | ||||||
| sti(void) | sti(void) | ||||||
| { | { | ||||||
| 	__asm__ volatile("sti"); |   __asm__ volatile("sti"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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 */ | ||||||
|     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
		Add a link
		
	
		Reference in a new issue
	
	 rsc
						rsc