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…
Reference in a new issue