spacing fixes: no tabs, 2-space indents (for rtm)
This commit is contained in:
parent
45854caa93
commit
a650c606fe
27
asm.h
27
asm.h
|
@ -2,17 +2,18 @@
|
|||
// macros to create x86 segments from assembler
|
||||
//
|
||||
|
||||
#define SEG_NULLASM \
|
||||
.word 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 SEG_NULLASM \
|
||||
.word 0, 0; \
|
||||
.byte 0, 0, 0, 0
|
||||
|
||||
#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
|
||||
#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 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"
|
||||
|
||||
.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 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.
|
||||
# After the BIOS initializes the hardware on startup or system reset,
|
||||
# it loads this code at physical address 0x7c00 - 0x7d00 (512 bytes).
|
||||
# Then the BIOS jumps to the beginning of it, address 0x7c00,
|
||||
# while running in 16-bit real-mode (8086 compatibility mode).
|
||||
# The Code Segment register (CS) is initially zero on entry.
|
||||
#
|
||||
#
|
||||
# This code switches into 32-bit protected mode so that all of
|
||||
# memory can accessed, then calls into C.
|
||||
###################################################################################
|
||||
|
||||
.globl start # Entry point
|
||||
start: .code16 # This runs in real mode
|
||||
cli # Disable interrupts
|
||||
cld # String operations increment
|
||||
|
||||
.globl start # Entry point
|
||||
start:
|
||||
.code16 # This runs in real mode
|
||||
cli # Disable interrupts
|
||||
cld # String operations increment
|
||||
|
||||
# Set up the important data segment registers (DS, ES, SS).
|
||||
xorw %ax,%ax # Segment number zero
|
||||
movw %ax,%ds # -> Data Segment
|
||||
movw %ax,%es # -> Extra Segment
|
||||
movw %ax,%ss # -> Stack Segment
|
||||
# Set up the important data segment registers (DS, ES, SS).
|
||||
xorw %ax,%ax # Segment number zero
|
||||
movw %ax,%ds # -> Data Segment
|
||||
movw %ax,%es # -> Extra Segment
|
||||
movw %ax,%ss # -> Stack Segment
|
||||
|
||||
# Set up the stack pointer, growing downward from 0x7c00.
|
||||
movw $start,%sp # Stack Pointer
|
||||
|
||||
# Set up the stack pointer, growing downward from 0x7c00.
|
||||
movw $start,%sp # Stack Pointer
|
||||
|
||||
#### Enable A20:
|
||||
#### For fascinating historical reasons (related to the fact that
|
||||
#### 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.
|
||||
#### Obviously this a bit of a drag for us, especially when trying to
|
||||
#### address memory above 1MB. This code undoes this.
|
||||
|
||||
seta20.1: inb $0x64,%al # Get status
|
||||
testb $0x2,%al # Busy?
|
||||
jnz seta20.1 # Yes
|
||||
movb $0xd1,%al # Command: Write
|
||||
outb %al,$0x64 # output port
|
||||
seta20.2: inb $0x64,%al # Get status
|
||||
testb $0x2,%al # Busy?
|
||||
jnz seta20.2 # Yes
|
||||
movb $0xdf,%al # Enable
|
||||
outb %al,$0x60 # A20
|
||||
|
||||
seta20.1:
|
||||
inb $0x64,%al # Get status
|
||||
testb $0x2,%al # Busy?
|
||||
jnz seta20.1 # Yes
|
||||
movb $0xd1,%al # Command: Write
|
||||
outb %al,$0x64 # output port
|
||||
|
||||
#### 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.
|
||||
#### Furthermore, the descriptors have base addresses of 0, so that the
|
||||
#### segment translation is a NOP, ie. virtual addresses are identical to
|
||||
#### their physical addresses. With this setup, immediately after
|
||||
#### enabling protected mode it will still appear to this code
|
||||
#### that it is running directly on physical memory with no translation.
|
||||
#### This initial NOP-translation setup is required by the processor
|
||||
#### to ensure that the transition to protected mode occurs smoothly.
|
||||
|
||||
real_to_prot: cli # Mandatory since we dont set up an IDT
|
||||
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
||||
movl %cr0, %eax # turn on protected mode
|
||||
orl $CR0_PE_ON, %eax #
|
||||
movl %eax, %cr0 #
|
||||
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
|
||||
### Has the effect of just jmp to the next instruction, but simultaneous
|
||||
### loads CS with $PROT_MODE_CSEG.
|
||||
ljmp $PROT_MODE_CSEG, $protcseg
|
||||
|
||||
#### enabling protected mode it will still appear to this code
|
||||
#### that it is running directly on physical memory with no translation.
|
||||
#### This initial NOP-translation setup is required by the processor
|
||||
#### to ensure that the transition to protected mode occurs smoothly.
|
||||
|
||||
real_to_prot:
|
||||
cli # Mandatory since we dont set up an IDT
|
||||
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
||||
movl %cr0, %eax # turn on protected mode
|
||||
orl $CR0_PE_ON, %eax #
|
||||
movl %eax, %cr0 #
|
||||
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
|
||||
### Has the effect of just jmp to the next instruction, but simultaneous
|
||||
### loads CS with $PROT_MODE_CSEG.
|
||||
ljmp $PROT_MODE_CSEG, $protcseg
|
||||
|
||||
#### we are in 32-bit protected mode (hence the .code32)
|
||||
.code32
|
||||
protcseg:
|
||||
# Set up the protected-mode data segment registers
|
||||
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
||||
movw %ax, %ds # -> DS: Data Segment
|
||||
movw %ax, %es # -> ES: Extra Segment
|
||||
movw %ax, %fs # -> FS
|
||||
movw %ax, %gs # -> GS
|
||||
movw %ax, %ss # -> SS: Stack Segment
|
||||
|
||||
call cmain # finish the boot load from C.
|
||||
# cmain() should not return
|
||||
spin: jmp spin # ..but in case it does, spin
|
||||
|
||||
.p2align 2 # force 4 byte alignment
|
||||
protcseg:
|
||||
# Set up the protected-mode data segment registers
|
||||
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
||||
movw %ax, %ds # -> DS: Data Segment
|
||||
movw %ax, %es # -> ES: Extra Segment
|
||||
movw %ax, %fs # -> FS
|
||||
movw %ax, %gs # -> GS
|
||||
movw %ax, %ss # -> SS: Stack Segment
|
||||
|
||||
call cmain # finish the boot load from C.
|
||||
# cmain() should not return
|
||||
spin:
|
||||
jmp spin # ..but in case it does, spin
|
||||
|
||||
|
||||
.p2align 2 # force 4 byte alignment
|
||||
gdt:
|
||||
SEG_NULLASM # null seg
|
||||
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
|
||||
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
||||
|
||||
SEG_NULLASM # null seg
|
||||
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
|
||||
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
||||
|
||||
gdtdesc:
|
||||
.word 0x17 # sizeof(gdt) - 1
|
||||
.long gdt # address gdt
|
||||
.word 0x17 # sizeof(gdt) - 1
|
||||
.long gdt # address gdt
|
||||
|
|
106
bootmain.c
106
bootmain.c
|
@ -11,10 +11,10 @@
|
|||
* be stored in the first sector of the disk.
|
||||
*
|
||||
* * The 2nd sector onward holds the kernel image.
|
||||
*
|
||||
*
|
||||
* * The kernel image must be in ELF format.
|
||||
*
|
||||
* BOOT UP STEPS
|
||||
* BOOT UP STEPS
|
||||
* * when the CPU boots it loads the BIOS into memory and executes it
|
||||
*
|
||||
* * the BIOS intializes devices, sets of the interrupt routines, and
|
||||
|
@ -30,8 +30,8 @@
|
|||
* * cmain() in this file takes over, reads in the kernel and jumps to it.
|
||||
**********************************************************************/
|
||||
|
||||
#define SECTSIZE 512
|
||||
#define ELFHDR ((struct elfhdr *) 0x10000) // scratch space
|
||||
#define SECTSIZE 512
|
||||
#define ELFHDR ((struct elfhdr *) 0x10000) // scratch space
|
||||
|
||||
void readsect(void*, uint);
|
||||
void readseg(uint, uint, uint);
|
||||
|
@ -39,30 +39,30 @@ void readseg(uint, uint, uint);
|
|||
void
|
||||
cmain(void)
|
||||
{
|
||||
struct proghdr *ph, *eph;
|
||||
struct proghdr *ph, *eph;
|
||||
|
||||
// read 1st page off disk
|
||||
readseg((uint) ELFHDR, SECTSIZE*8, 0);
|
||||
// read 1st page off disk
|
||||
readseg((uint) ELFHDR, SECTSIZE*8, 0);
|
||||
|
||||
// is this a valid ELF?
|
||||
if (ELFHDR->magic != ELF_MAGIC)
|
||||
goto bad;
|
||||
// is this a valid ELF?
|
||||
if (ELFHDR->magic != ELF_MAGIC)
|
||||
goto bad;
|
||||
|
||||
// load each program segment (ignores ph flags)
|
||||
ph = (struct proghdr *) ((uchar *) ELFHDR + ELFHDR->phoff);
|
||||
eph = ph + ELFHDR->phnum;
|
||||
for (; ph < eph; ph++)
|
||||
readseg(ph->va, ph->memsz, ph->offset);
|
||||
// load each program segment (ignores ph flags)
|
||||
ph = (struct proghdr *) ((uchar *) ELFHDR + ELFHDR->phoff);
|
||||
eph = ph + ELFHDR->phnum;
|
||||
for (; ph < eph; ph++)
|
||||
readseg(ph->va, ph->memsz, ph->offset);
|
||||
|
||||
// call the entry point from the ELF header
|
||||
// note: does not return!
|
||||
((void (*)(void)) (ELFHDR->entry & 0xFFFFFF))();
|
||||
// call the entry point from the ELF header
|
||||
// note: does not return!
|
||||
((void (*)(void)) (ELFHDR->entry & 0xFFFFFF))();
|
||||
|
||||
bad:
|
||||
outw(0x8A00, 0x8A00);
|
||||
outw(0x8A00, 0x8E00);
|
||||
while(1)
|
||||
/* do nothing */;
|
||||
outw(0x8A00, 0x8A00);
|
||||
outw(0x8A00, 0x8E00);
|
||||
while(1)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.
|
||||
|
@ -70,52 +70,52 @@ bad:
|
|||
void
|
||||
readseg(uint va, uint count, uint offset)
|
||||
{
|
||||
uint end_va;
|
||||
uint end_va;
|
||||
|
||||
va &= 0xFFFFFF;
|
||||
end_va = va + count;
|
||||
|
||||
// round down to sector boundary
|
||||
va &= ~(SECTSIZE - 1);
|
||||
va &= 0xFFFFFF;
|
||||
end_va = va + count;
|
||||
|
||||
// round down to sector boundary
|
||||
va &= ~(SECTSIZE - 1);
|
||||
|
||||
// translate from bytes to sectors, and kernel starts at sector 1
|
||||
offset = (offset / SECTSIZE) + 1;
|
||||
// translate from bytes to sectors, and kernel starts at sector 1
|
||||
offset = (offset / SECTSIZE) + 1;
|
||||
|
||||
// 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 load in increasing order.
|
||||
while (va < end_va) {
|
||||
readsect((uchar*) va, offset);
|
||||
va += SECTSIZE;
|
||||
offset++;
|
||||
}
|
||||
// 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 load in increasing order.
|
||||
while (va < end_va) {
|
||||
readsect((uchar*) va, offset);
|
||||
va += SECTSIZE;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
waitdisk(void)
|
||||
{
|
||||
// wait for disk reaady
|
||||
while ((inb(0x1F7) & 0xC0) != 0x40)
|
||||
/* do nothing */;
|
||||
// wait for disk reaady
|
||||
while ((inb(0x1F7) & 0xC0) != 0x40)
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
void
|
||||
readsect(void *dst, uint offset)
|
||||
{
|
||||
// wait for disk to be ready
|
||||
waitdisk();
|
||||
// wait for disk to be ready
|
||||
waitdisk();
|
||||
|
||||
outb(0x1F2, 1); // count = 1
|
||||
outb(0x1F3, offset);
|
||||
outb(0x1F4, offset >> 8);
|
||||
outb(0x1F5, offset >> 16);
|
||||
outb(0x1F6, (offset >> 24) | 0xE0);
|
||||
outb(0x1F7, 0x20); // cmd 0x20 - read sectors
|
||||
outb(0x1F2, 1); // count = 1
|
||||
outb(0x1F3, offset);
|
||||
outb(0x1F4, offset >> 8);
|
||||
outb(0x1F5, offset >> 16);
|
||||
outb(0x1F6, (offset >> 24) | 0xE0);
|
||||
outb(0x1F7, 0x20); // cmd 0x20 - read sectors
|
||||
|
||||
// wait for disk to be ready
|
||||
waitdisk();
|
||||
// wait for disk to be ready
|
||||
waitdisk();
|
||||
|
||||
// read a sector
|
||||
insl(0x1F0, dst, SECTSIZE/4);
|
||||
// read a sector
|
||||
insl(0x1F0, dst, SECTSIZE/4);
|
||||
}
|
||||
|
||||
|
|
99
bootother.S
99
bootother.S
|
@ -1,5 +1,5 @@
|
|||
#include "asm.h"
|
||||
|
||||
|
||||
/*
|
||||
* Start an Application Processor. This must be placed on a 4KB boundary
|
||||
* 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 puts the correct %esp in start-4, and the place to jump
|
||||
* 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 CR0_PE_ON,0x1 # protected mode enable flag
|
||||
.set CR0_PE_ON,0x1 # protected mode enable flag
|
||||
|
||||
.globl start
|
||||
start: .code16 # This runs in real mode
|
||||
cli # Disable interrupts
|
||||
cld # String operations increment
|
||||
start:
|
||||
.code16 # This runs in real mode
|
||||
cli # Disable interrupts
|
||||
cld # String operations increment
|
||||
|
||||
# Set up the important data segment registers (DS, ES, SS).
|
||||
xorw %ax,%ax # Segment number zero
|
||||
movw %ax,%ds # -> Data Segment
|
||||
movw %ax,%es # -> Extra Segment
|
||||
movw %ax,%ss # -> Stack Segment
|
||||
# Set up the important data segment registers (DS, ES, SS).
|
||||
xorw %ax,%ax # Segment number zero
|
||||
movw %ax,%ds # -> Data Segment
|
||||
movw %ax,%es # -> Extra Segment
|
||||
movw %ax,%ss # -> Stack Segment
|
||||
|
||||
# Set up the stack pointer, growing downward from 0x7000-8.
|
||||
movw $start-8,%sp # Stack Pointer
|
||||
|
||||
#### Switch from real to protected mode
|
||||
# Set up the stack pointer, growing downward from 0x7000-8.
|
||||
movw $start-8,%sp # Stack Pointer
|
||||
|
||||
#### Switch from real to protected mode
|
||||
#### The descriptors in our GDT allow all physical memory to be accessed.
|
||||
#### Furthermore, the descriptors have base addresses of 0, so that the
|
||||
#### segment translation is a NOP, ie. virtual addresses are identical to
|
||||
#### their physical addresses. With this setup, immediately after
|
||||
#### enabling protected mode it will still appear to this code
|
||||
#### that it is running directly on physical memory with no translation.
|
||||
#### This initial NOP-translation setup is required by the processor
|
||||
#### to ensure that the transition to protected mode occurs smoothly.
|
||||
|
||||
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
||||
movl %cr0, %eax # turn on protected mode
|
||||
orl $CR0_PE_ON, %eax #
|
||||
movl %eax, %cr0 #
|
||||
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
|
||||
### Has the effect of just jmp to the next instruction, but simultaneous
|
||||
### loads CS with $PROT_MODE_CSEG.
|
||||
ljmp $PROT_MODE_CSEG, $protcseg
|
||||
|
||||
#### enabling protected mode it will still appear to this code
|
||||
#### that it is running directly on physical memory with no translation.
|
||||
#### This initial NOP-translation setup is required by the processor
|
||||
#### to ensure that the transition to protected mode occurs smoothly.
|
||||
|
||||
lgdt gdtdesc # load GDT -- mandatory in protected mode
|
||||
movl %cr0, %eax # turn on protected mode
|
||||
orl $CR0_PE_ON, %eax #
|
||||
movl %eax, %cr0 #
|
||||
### CPU magic: jump to relocation, flush prefetch queue, and reload %cs
|
||||
### Has the effect of just jmp to the next instruction, but simultaneous
|
||||
### loads CS with $PROT_MODE_CSEG.
|
||||
ljmp $PROT_MODE_CSEG, $protcseg
|
||||
|
||||
#### we are in 32-bit protected mode (hence the .code32)
|
||||
.code32
|
||||
protcseg:
|
||||
# Set up the protected-mode data segment registers
|
||||
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
||||
movw %ax, %ds # -> DS: Data Segment
|
||||
movw %ax, %es # -> ES: Extra Segment
|
||||
movw %ax, %fs # -> FS
|
||||
movw %ax, %gs # -> GS
|
||||
movw %ax, %ss # -> SS: Stack Segment
|
||||
protcseg:
|
||||
# Set up the protected-mode data segment registers
|
||||
movw $PROT_MODE_DSEG, %ax # Our data segment selector
|
||||
movw %ax, %ds # -> DS: Data Segment
|
||||
movw %ax, %es # -> ES: Extra Segment
|
||||
movw %ax, %fs # -> FS
|
||||
movw %ax, %gs # -> GS
|
||||
movw %ax, %ss # -> SS: Stack Segment
|
||||
|
||||
movl start-8, %eax
|
||||
movl start-4, %esp
|
||||
jmp *%eax
|
||||
|
||||
.p2align 2 # force 4 byte alignment
|
||||
movl start-8, %eax
|
||||
movl start-4, %esp
|
||||
jmp *%eax
|
||||
|
||||
.p2align 2 # force 4 byte alignment
|
||||
gdt:
|
||||
SEG_NULLASM # null seg
|
||||
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
|
||||
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
||||
|
||||
SEG_NULLASM # null seg
|
||||
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
|
||||
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
|
||||
|
||||
gdtdesc:
|
||||
.word 0x17 # sizeof(gdt) - 1
|
||||
.long gdt # address gdt
|
||||
.word 0x17 # sizeof(gdt) - 1
|
||||
.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++){
|
||||
fd = open(argv[i], 0);
|
||||
if(fd < 0){
|
||||
puts("cat: cannot open ");
|
||||
puts(argv[i]);
|
||||
puts("\n");
|
||||
exit();
|
||||
puts("cat: cannot open ");
|
||||
puts(argv[i]);
|
||||
puts("\n");
|
||||
exit();
|
||||
}
|
||||
rfile(fd);
|
||||
close(fd);
|
||||
|
|
174
console.c
174
console.c
|
@ -18,13 +18,13 @@ int use_console_lock = 0;
|
|||
static void
|
||||
lpt_putc(int c)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
|
||||
;
|
||||
outb(0x378+0, c);
|
||||
outb(0x378+2, 0x08|0x04|0x01);
|
||||
outb(0x378+2, 0x08);
|
||||
for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
|
||||
;
|
||||
outb(0x378+0, c);
|
||||
outb(0x378+2, 0x08|0x04|0x01);
|
||||
outb(0x378+2, 0x08);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -183,117 +183,117 @@ console_write (int minor, char *buf, int n)
|
|||
|
||||
|
||||
/* This is i8042reg.h + kbdreg.h from NetBSD. */
|
||||
#define KBSTATP 0x64 /* kbd controller status port(I) */
|
||||
#define KBS_DIB 0x01 /* kbd data in buffer */
|
||||
#define KBDATAP 0x60 /* kbd data port(I) */
|
||||
#define KBSTATP 0x64 /* kbd controller status port(I) */
|
||||
#define KBS_DIB 0x01 /* kbd data in buffer */
|
||||
#define KBDATAP 0x60 /* kbd data port(I) */
|
||||
|
||||
#define NO 0
|
||||
#define NO 0
|
||||
|
||||
#define SHIFT (1<<0)
|
||||
#define CTL (1<<1)
|
||||
#define ALT (1<<2)
|
||||
#define SHIFT (1<<0)
|
||||
#define CTL (1<<1)
|
||||
#define ALT (1<<2)
|
||||
|
||||
#define CAPSLOCK (1<<3)
|
||||
#define NUMLOCK (1<<4)
|
||||
#define SCROLLLOCK (1<<5)
|
||||
#define CAPSLOCK (1<<3)
|
||||
#define NUMLOCK (1<<4)
|
||||
#define SCROLLLOCK (1<<5)
|
||||
|
||||
#define E0ESC (1<<6)
|
||||
#define E0ESC (1<<6)
|
||||
|
||||
// Special keycodes
|
||||
#define KEY_HOME 0xE0
|
||||
#define KEY_END 0xE1
|
||||
#define KEY_UP 0xE2
|
||||
#define KEY_DN 0xE3
|
||||
#define KEY_LF 0xE4
|
||||
#define KEY_RT 0xE5
|
||||
#define KEY_PGUP 0xE6
|
||||
#define KEY_PGDN 0xE7
|
||||
#define KEY_INS 0xE8
|
||||
#define KEY_DEL 0xE9
|
||||
#define KEY_HOME 0xE0
|
||||
#define KEY_END 0xE1
|
||||
#define KEY_UP 0xE2
|
||||
#define KEY_DN 0xE3
|
||||
#define KEY_LF 0xE4
|
||||
#define KEY_RT 0xE5
|
||||
#define KEY_PGUP 0xE6
|
||||
#define KEY_PGDN 0xE7
|
||||
#define KEY_INS 0xE8
|
||||
#define KEY_DEL 0xE9
|
||||
|
||||
static uchar shiftcode[256] =
|
||||
{
|
||||
[0x1D] CTL,
|
||||
[0x2A] SHIFT,
|
||||
[0x36] SHIFT,
|
||||
[0x38] ALT,
|
||||
[0x9D] CTL,
|
||||
[0xB8] ALT
|
||||
[0x1D] CTL,
|
||||
[0x2A] SHIFT,
|
||||
[0x36] SHIFT,
|
||||
[0x38] ALT,
|
||||
[0x9D] CTL,
|
||||
[0xB8] ALT
|
||||
};
|
||||
|
||||
static uchar togglecode[256] =
|
||||
{
|
||||
[0x3A] CAPSLOCK,
|
||||
[0x45] NUMLOCK,
|
||||
[0x46] SCROLLLOCK
|
||||
[0x3A] CAPSLOCK,
|
||||
[0x45] NUMLOCK,
|
||||
[0x46] SCROLLLOCK
|
||||
};
|
||||
|
||||
static uchar normalmap[256] =
|
||||
{
|
||||
NO, 0x1B, '1', '2', '3', '4', '5', '6', // 0x00
|
||||
'7', '8', '9', '0', '-', '=', '\b', '\t',
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 0x10
|
||||
'o', 'p', '[', ']', '\n', NO, 'a', 's',
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 0x20
|
||||
'\'', '`', NO, '\\', 'z', 'x', 'c', 'v',
|
||||
'b', 'n', 'm', ',', '.', '/', NO, '*', // 0x30
|
||||
NO, ' ', NO, NO, NO, NO, NO, NO,
|
||||
NO, NO, NO, NO, NO, NO, NO, '7', // 0x40
|
||||
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', NO, NO, NO, NO, // 0x50
|
||||
[0x97] KEY_HOME, [0x9C] '\n' /*KP_Enter*/,
|
||||
[0xB5] '/' /*KP_Div*/, [0xC8] KEY_UP,
|
||||
[0xC9] KEY_PGUP, [0xCB] KEY_LF,
|
||||
[0xCD] KEY_RT, [0xCF] KEY_END,
|
||||
[0xD0] KEY_DN, [0xD1] KEY_PGDN,
|
||||
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
||||
NO, 0x1B, '1', '2', '3', '4', '5', '6', // 0x00
|
||||
'7', '8', '9', '0', '-', '=', '\b', '\t',
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 0x10
|
||||
'o', 'p', '[', ']', '\n', NO, 'a', 's',
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', // 0x20
|
||||
'\'', '`', NO, '\\', 'z', 'x', 'c', 'v',
|
||||
'b', 'n', 'm', ',', '.', '/', NO, '*', // 0x30
|
||||
NO, ' ', NO, NO, NO, NO, NO, NO,
|
||||
NO, NO, NO, NO, NO, NO, NO, '7', // 0x40
|
||||
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', NO, NO, NO, NO, // 0x50
|
||||
[0x97] KEY_HOME, [0x9C] '\n' /*KP_Enter*/,
|
||||
[0xB5] '/' /*KP_Div*/, [0xC8] KEY_UP,
|
||||
[0xC9] KEY_PGUP, [0xCB] KEY_LF,
|
||||
[0xCD] KEY_RT, [0xCF] KEY_END,
|
||||
[0xD0] KEY_DN, [0xD1] KEY_PGDN,
|
||||
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
||||
};
|
||||
|
||||
static uchar shiftmap[256] =
|
||||
{
|
||||
NO, 033, '!', '@', '#', '$', '%', '^', // 0x00
|
||||
'&', '*', '(', ')', '_', '+', '\b', '\t',
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', // 0x10
|
||||
'O', 'P', '{', '}', '\n', NO, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 0x20
|
||||
'"', '~', NO, '|', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', '<', '>', '?', NO, '*', // 0x30
|
||||
NO, ' ', NO, NO, NO, NO, NO, NO,
|
||||
NO, NO, NO, NO, NO, NO, NO, '7', // 0x40
|
||||
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', NO, NO, NO, NO, // 0x50
|
||||
[0x97] KEY_HOME, [0x9C] '\n' /*KP_Enter*/,
|
||||
[0xB5] '/' /*KP_Div*/, [0xC8] KEY_UP,
|
||||
[0xC9] KEY_PGUP, [0xCB] KEY_LF,
|
||||
[0xCD] KEY_RT, [0xCF] KEY_END,
|
||||
[0xD0] KEY_DN, [0xD1] KEY_PGDN,
|
||||
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
||||
NO, 033, '!', '@', '#', '$', '%', '^', // 0x00
|
||||
'&', '*', '(', ')', '_', '+', '\b', '\t',
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', // 0x10
|
||||
'O', 'P', '{', '}', '\n', NO, 'A', 'S',
|
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', // 0x20
|
||||
'"', '~', NO, '|', 'Z', 'X', 'C', 'V',
|
||||
'B', 'N', 'M', '<', '>', '?', NO, '*', // 0x30
|
||||
NO, ' ', NO, NO, NO, NO, NO, NO,
|
||||
NO, NO, NO, NO, NO, NO, NO, '7', // 0x40
|
||||
'8', '9', '-', '4', '5', '6', '+', '1',
|
||||
'2', '3', '0', '.', NO, NO, NO, NO, // 0x50
|
||||
[0x97] KEY_HOME, [0x9C] '\n' /*KP_Enter*/,
|
||||
[0xB5] '/' /*KP_Div*/, [0xC8] KEY_UP,
|
||||
[0xC9] KEY_PGUP, [0xCB] KEY_LF,
|
||||
[0xCD] KEY_RT, [0xCF] KEY_END,
|
||||
[0xD0] KEY_DN, [0xD1] KEY_PGDN,
|
||||
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
||||
};
|
||||
|
||||
#define C(x) (x - '@')
|
||||
|
||||
static uchar ctlmap[256] =
|
||||
{
|
||||
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('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,
|
||||
NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'),
|
||||
C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO,
|
||||
[0x97] KEY_HOME,
|
||||
[0xB5] C('/'), [0xC8] KEY_UP,
|
||||
[0xC9] KEY_PGUP, [0xCB] KEY_LF,
|
||||
[0xCD] KEY_RT, [0xCF] KEY_END,
|
||||
[0xD0] KEY_DN, [0xD1] KEY_PGDN,
|
||||
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
||||
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('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,
|
||||
NO, NO, NO, C('\\'), C('Z'), C('X'), C('C'), C('V'),
|
||||
C('B'), C('N'), C('M'), NO, NO, C('/'), NO, NO,
|
||||
[0x97] KEY_HOME,
|
||||
[0xB5] C('/'), [0xC8] KEY_UP,
|
||||
[0xC9] KEY_PGUP, [0xCB] KEY_LF,
|
||||
[0xCD] KEY_RT, [0xCF] KEY_END,
|
||||
[0xD0] KEY_DN, [0xD1] KEY_PGDN,
|
||||
[0xD2] KEY_INS, [0xD3] KEY_DEL
|
||||
};
|
||||
|
||||
static uchar *charcode[4] = {
|
||||
normalmap,
|
||||
shiftmap,
|
||||
ctlmap,
|
||||
ctlmap
|
||||
normalmap,
|
||||
shiftmap,
|
||||
ctlmap,
|
||||
ctlmap
|
||||
};
|
||||
|
||||
#define KBD_BUF 64
|
||||
|
|
46
elf.h
46
elf.h
|
@ -5,32 +5,32 @@
|
|||
#define ELF_MAGIC 0x464C457FU /* "\x7FELF" in little endian */
|
||||
|
||||
struct elfhdr {
|
||||
uint magic; // must equal ELF_MAGIC
|
||||
uchar elf[12];
|
||||
ushort type;
|
||||
ushort machine;
|
||||
uint version;
|
||||
uint entry;
|
||||
uint phoff;
|
||||
uint shoff;
|
||||
uint flags;
|
||||
ushort ehsize;
|
||||
ushort phentsize;
|
||||
ushort phnum;
|
||||
ushort shentsize;
|
||||
ushort shnum;
|
||||
ushort shstrndx;
|
||||
uint magic; // must equal ELF_MAGIC
|
||||
uchar elf[12];
|
||||
ushort type;
|
||||
ushort machine;
|
||||
uint version;
|
||||
uint entry;
|
||||
uint phoff;
|
||||
uint shoff;
|
||||
uint flags;
|
||||
ushort ehsize;
|
||||
ushort phentsize;
|
||||
ushort phnum;
|
||||
ushort shentsize;
|
||||
ushort shnum;
|
||||
ushort shstrndx;
|
||||
};
|
||||
|
||||
struct proghdr {
|
||||
uint type;
|
||||
uint offset;
|
||||
uint va;
|
||||
uint pa;
|
||||
uint filesz;
|
||||
uint memsz;
|
||||
uint flags;
|
||||
uint align;
|
||||
uint type;
|
||||
uint offset;
|
||||
uint va;
|
||||
uint pa;
|
||||
uint filesz;
|
||||
uint memsz;
|
||||
uint flags;
|
||||
uint align;
|
||||
};
|
||||
|
||||
// Values for Proghdr type
|
||||
|
|
26
fs.c
26
fs.c
|
@ -270,16 +270,16 @@ itrunc(struct inode *ip)
|
|||
for (i = 0; i < NADDRS; i++) {
|
||||
if (ip->addrs[i] != 0) {
|
||||
if (i == INDIRECT) {
|
||||
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
||||
inbp = bread(ip->dev, ip->addrs[INDIRECT]);
|
||||
uint *a = (uint *) inbp->data;
|
||||
for (j = 0; j < NINDIRECT; j++) {
|
||||
if (a[j] != 0) {
|
||||
bfree(ip->dev, a[j]);
|
||||
a[j] = 0;
|
||||
}
|
||||
}
|
||||
brelse(inbp);
|
||||
}
|
||||
for (j = 0; j < NINDIRECT; j++) {
|
||||
if (a[j] != 0) {
|
||||
bfree(ip->dev, a[j]);
|
||||
a[j] = 0;
|
||||
}
|
||||
}
|
||||
brelse(inbp);
|
||||
}
|
||||
bfree(ip->dev, ip->addrs[i]);
|
||||
ip->addrs[i] = 0;
|
||||
}
|
||||
|
@ -411,8 +411,8 @@ writei(struct inode *ip, char *addr, uint off, uint n)
|
|||
lbn = off / BSIZE;
|
||||
if (lbn >= MAXFILE) return r;
|
||||
if (newblock(ip, lbn) < 0) {
|
||||
cprintf("newblock failed\n");
|
||||
return r;
|
||||
cprintf("newblock failed\n");
|
||||
return r;
|
||||
}
|
||||
m = min(BSIZE - off % BSIZE, n-r);
|
||||
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 (off > ip->size) {
|
||||
if (ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE;
|
||||
else ip->size = off;
|
||||
if (ip->type == T_DIR) ip->size = ((off / BSIZE) + 1) * BSIZE;
|
||||
else ip->size = off;
|
||||
}
|
||||
iupdate(ip);
|
||||
}
|
||||
|
|
9
ide.c
9
ide.c
|
@ -11,8 +11,8 @@
|
|||
#include "traps.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
#define IDE_BSY 0x80
|
||||
#define IDE_DRDY 0x40
|
||||
#define IDE_BSY 0x80
|
||||
#define IDE_DRDY 0x40
|
||||
#define IDE_DF 0x20
|
||||
#define IDE_ERR 0x01
|
||||
|
||||
|
@ -23,6 +23,7 @@ struct ide_request {
|
|||
uint nsecs;
|
||||
uint read;
|
||||
};
|
||||
|
||||
struct ide_request request[NREQUEST];
|
||||
int head, tail;
|
||||
struct spinlock ide_lock;
|
||||
|
@ -154,7 +155,7 @@ int
|
|||
ide_write(int diskno, uint secno, const void *src, uint nsecs)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
||||
if(nsecs > 256)
|
||||
panic("ide_write");
|
||||
|
||||
|
@ -165,7 +166,7 @@ ide_write(int diskno, uint secno, const void *src, uint nsecs)
|
|||
outb(0x1F4, (secno >> 8) & 0xFF);
|
||||
outb(0x1F5, (secno >> 16) & 0xFF);
|
||||
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
|
||||
outb(0x1F7, 0x30); // CMD 0x30 means write sector
|
||||
outb(0x1F7, 0x30); // CMD 0x30 means write sector
|
||||
|
||||
for (; nsecs > 0; nsecs--, src += 512) {
|
||||
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_HI(i) (IOAPIC_REDTBL_LO(i) + 1)
|
||||
#define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2)
|
||||
#define IOAPIC_REDTBL_HI(i) (IOAPIC_REDTBL_LO(i) + 1)
|
||||
|
||||
static uint
|
||||
ioapic_read(struct ioapic *io, int reg)
|
||||
|
@ -40,7 +40,7 @@ ioapic_init(void)
|
|||
io = (struct ioapic *) IO_APIC_BASE;
|
||||
l = ioapic_read(io, IOAPIC_VER);
|
||||
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)
|
||||
panic ("ioapic_init: id isn't equal to ioapic_id\n");
|
||||
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 IOAPIC_WINDOW 0x10 /* window register offset */
|
||||
#define IO_APIC_BASE 0xFEC00000 /* default physical locations of an IO APIC */
|
||||
#define IOAPIC_WINDOW 0x10 /* window register offset */
|
||||
|
||||
/* constants relating to APIC ID registers */
|
||||
#define APIC_ID_MASK 0xff000000
|
||||
#define APIC_ID_SHIFT 24
|
||||
#define APIC_ID_CLUSTER 0xf0
|
||||
#define APIC_ID_CLUSTER_ID 0x0f
|
||||
#define APIC_MAX_CLUSTER 0xe
|
||||
#define APIC_MAX_INTRACLUSTER_ID 3
|
||||
#define APIC_ID_CLUSTER_SHIFT 4
|
||||
#define APIC_ID_MASK 0xff000000
|
||||
#define APIC_ID_SHIFT 24
|
||||
#define APIC_ID_CLUSTER 0xf0
|
||||
#define APIC_ID_CLUSTER_ID 0x0f
|
||||
#define APIC_MAX_CLUSTER 0xe
|
||||
#define APIC_MAX_INTRACLUSTER_ID 3
|
||||
#define APIC_ID_CLUSTER_SHIFT 4
|
||||
|
||||
/* fields in VER */
|
||||
#define APIC_VER_VERSION 0x000000ff
|
||||
#define APIC_VER_MAXLVT 0x00ff0000
|
||||
#define MAXLVTSHIFT 16
|
||||
#define APIC_VER_VERSION 0x000000ff
|
||||
#define APIC_VER_MAXLVT 0x00ff0000
|
||||
#define MAXLVTSHIFT 16
|
||||
|
||||
/* Indexes into IO APIC */
|
||||
#define IOAPIC_ID 0x00
|
||||
#define IOAPIC_VER 0x01
|
||||
#define IOAPIC_ARB 0x02
|
||||
#define IOAPIC_REDTBL 0x10
|
||||
#define IOAPIC_REDTBL0 IOAPIC_REDTBL
|
||||
#define IOAPIC_REDTBL1 (IOAPIC_REDTBL+0x02)
|
||||
#define IOAPIC_REDTBL2 (IOAPIC_REDTBL+0x04)
|
||||
#define IOAPIC_REDTBL3 (IOAPIC_REDTBL+0x06)
|
||||
#define IOAPIC_REDTBL4 (IOAPIC_REDTBL+0x08)
|
||||
#define IOAPIC_REDTBL5 (IOAPIC_REDTBL+0x0a)
|
||||
#define IOAPIC_REDTBL6 (IOAPIC_REDTBL+0x0c)
|
||||
#define IOAPIC_REDTBL7 (IOAPIC_REDTBL+0x0e)
|
||||
#define IOAPIC_REDTBL8 (IOAPIC_REDTBL+0x10)
|
||||
#define IOAPIC_REDTBL9 (IOAPIC_REDTBL+0x12)
|
||||
#define IOAPIC_REDTBL10 (IOAPIC_REDTBL+0x14)
|
||||
#define IOAPIC_REDTBL11 (IOAPIC_REDTBL+0x16)
|
||||
#define IOAPIC_REDTBL12 (IOAPIC_REDTBL+0x18)
|
||||
#define IOAPIC_REDTBL13 (IOAPIC_REDTBL+0x1a)
|
||||
#define IOAPIC_REDTBL14 (IOAPIC_REDTBL+0x1c)
|
||||
#define IOAPIC_REDTBL15 (IOAPIC_REDTBL+0x1e)
|
||||
#define IOAPIC_REDTBL16 (IOAPIC_REDTBL+0x20)
|
||||
#define IOAPIC_REDTBL17 (IOAPIC_REDTBL+0x22)
|
||||
#define IOAPIC_REDTBL18 (IOAPIC_REDTBL+0x24)
|
||||
#define IOAPIC_REDTBL19 (IOAPIC_REDTBL+0x26)
|
||||
#define IOAPIC_REDTBL20 (IOAPIC_REDTBL+0x28)
|
||||
#define IOAPIC_REDTBL21 (IOAPIC_REDTBL+0x2a)
|
||||
#define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2c)
|
||||
#define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2e)
|
||||
#define IOAPIC_ID 0x00
|
||||
#define IOAPIC_VER 0x01
|
||||
#define IOAPIC_ARB 0x02
|
||||
#define IOAPIC_REDTBL 0x10
|
||||
#define IOAPIC_REDTBL0 IOAPIC_REDTBL
|
||||
#define IOAPIC_REDTBL1 (IOAPIC_REDTBL+0x02)
|
||||
#define IOAPIC_REDTBL2 (IOAPIC_REDTBL+0x04)
|
||||
#define IOAPIC_REDTBL3 (IOAPIC_REDTBL+0x06)
|
||||
#define IOAPIC_REDTBL4 (IOAPIC_REDTBL+0x08)
|
||||
#define IOAPIC_REDTBL5 (IOAPIC_REDTBL+0x0a)
|
||||
#define IOAPIC_REDTBL6 (IOAPIC_REDTBL+0x0c)
|
||||
#define IOAPIC_REDTBL7 (IOAPIC_REDTBL+0x0e)
|
||||
#define IOAPIC_REDTBL8 (IOAPIC_REDTBL+0x10)
|
||||
#define IOAPIC_REDTBL9 (IOAPIC_REDTBL+0x12)
|
||||
#define IOAPIC_REDTBL10 (IOAPIC_REDTBL+0x14)
|
||||
#define IOAPIC_REDTBL11 (IOAPIC_REDTBL+0x16)
|
||||
#define IOAPIC_REDTBL12 (IOAPIC_REDTBL+0x18)
|
||||
#define IOAPIC_REDTBL13 (IOAPIC_REDTBL+0x1a)
|
||||
#define IOAPIC_REDTBL14 (IOAPIC_REDTBL+0x1c)
|
||||
#define IOAPIC_REDTBL15 (IOAPIC_REDTBL+0x1e)
|
||||
#define IOAPIC_REDTBL16 (IOAPIC_REDTBL+0x20)
|
||||
#define IOAPIC_REDTBL17 (IOAPIC_REDTBL+0x22)
|
||||
#define IOAPIC_REDTBL18 (IOAPIC_REDTBL+0x24)
|
||||
#define IOAPIC_REDTBL19 (IOAPIC_REDTBL+0x26)
|
||||
#define IOAPIC_REDTBL20 (IOAPIC_REDTBL+0x28)
|
||||
#define IOAPIC_REDTBL21 (IOAPIC_REDTBL+0x2a)
|
||||
#define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2c)
|
||||
#define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2e)
|
||||
|
||||
/*
|
||||
* fields in the IO APIC's redirection table entries
|
||||
*/
|
||||
#define IOART_DEST APIC_ID_MASK /* broadcast addr: all APICs */
|
||||
#define IOART_DEST APIC_ID_MASK /* broadcast addr: all APICs */
|
||||
|
||||
#define IOART_RESV 0x00fe0000 /* reserved */
|
||||
#define IOART_RESV 0x00fe0000 /* reserved */
|
||||
|
||||
#define IOART_INTMASK 0x00010000 /* R/W: INTerrupt mask */
|
||||
#define IOART_INTMCLR 0x00000000 /* clear, allow INTs */
|
||||
#define IOART_INTMSET 0x00010000 /* set, inhibit INTs */
|
||||
#define IOART_INTMASK 0x00010000 /* R/W: INTerrupt mask */
|
||||
#define IOART_INTMCLR 0x00000000 /* clear, allow INTs */
|
||||
#define IOART_INTMSET 0x00010000 /* set, inhibit INTs */
|
||||
|
||||
#define IOART_TRGRMOD 0x00008000 /* R/W: trigger mode */
|
||||
#define IOART_TRGREDG 0x00000000 /* edge */
|
||||
#define IOART_TRGRLVL 0x00008000 /* level */
|
||||
#define IOART_TRGRMOD 0x00008000 /* R/W: trigger mode */
|
||||
#define IOART_TRGREDG 0x00000000 /* edge */
|
||||
#define IOART_TRGRLVL 0x00008000 /* level */
|
||||
|
||||
#define IOART_REM_IRR 0x00004000 /* RO: remote IRR */
|
||||
#define IOART_REM_IRR 0x00004000 /* RO: remote IRR */
|
||||
|
||||
#define IOART_INTPOL 0x00002000 /* R/W: INT input pin polarity */
|
||||
#define IOART_INTAHI 0x00000000 /* active high */
|
||||
#define IOART_INTALO 0x00002000 /* active low */
|
||||
#define IOART_INTPOL 0x00002000 /* R/W: INT input pin polarity */
|
||||
#define IOART_INTAHI 0x00000000 /* active high */
|
||||
#define IOART_INTALO 0x00002000 /* active low */
|
||||
|
||||
#define IOART_DELIVS 0x00001000 /* RO: delivery status */
|
||||
#define IOART_DELIVS 0x00001000 /* RO: delivery status */
|
||||
|
||||
#define IOART_DESTMOD 0x00000800 /* R/W: destination mode */
|
||||
#define IOART_DESTPHY 0x00000000 /* physical */
|
||||
#define IOART_DESTLOG 0x00000800 /* logical */
|
||||
#define IOART_DESTMOD 0x00000800 /* R/W: destination mode */
|
||||
#define IOART_DESTPHY 0x00000000 /* physical */
|
||||
#define IOART_DESTLOG 0x00000800 /* logical */
|
||||
|
||||
#define IOART_DELMOD 0x00000700 /* R/W: delivery mode */
|
||||
#define IOART_DELFIXED 0x00000000 /* fixed */
|
||||
#define IOART_DELLOPRI 0x00000100 /* lowest priority */
|
||||
#define IOART_DELSMI 0x00000200 /* System Management INT */
|
||||
#define IOART_DELRSV1 0x00000300 /* reserved */
|
||||
#define IOART_DELNMI 0x00000400 /* NMI signal */
|
||||
#define IOART_DELINIT 0x00000500 /* INIT signal */
|
||||
#define IOART_DELRSV2 0x00000600 /* reserved */
|
||||
#define IOART_DELEXINT 0x00000700 /* External INTerrupt */
|
||||
#define IOART_DELMOD 0x00000700 /* R/W: delivery mode */
|
||||
#define IOART_DELFIXED 0x00000000 /* fixed */
|
||||
#define IOART_DELLOPRI 0x00000100 /* lowest priority */
|
||||
#define IOART_DELSMI 0x00000200 /* System Management INT */
|
||||
#define IOART_DELRSV1 0x00000300 /* reserved */
|
||||
#define IOART_DELNMI 0x00000400 /* NMI signal */
|
||||
#define IOART_DELINIT 0x00000500 /* INIT signal */
|
||||
#define IOART_DELRSV2 0x00000600 /* reserved */
|
||||
#define IOART_DELEXINT 0x00000700 /* External INTerrupt */
|
||||
|
||||
#define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */
|
||||
#define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */
|
||||
|
||||
/* fields in VER */
|
||||
#define IOART_VER_VERSION 0x000000ff
|
||||
#define IOART_VER_MAXREDIR 0x00ff0000
|
||||
#define MAXREDIRSHIFT 16
|
||||
#define IOART_VER_VERSION 0x000000ff
|
||||
#define IOART_VER_MAXREDIR 0x00ff0000
|
||||
#define MAXREDIRSHIFT 16
|
||||
|
|
18
ls.c
18
ls.c
|
@ -59,17 +59,17 @@ main(int argc, char *argv[])
|
|||
sz = st.st_size;
|
||||
for(off = 0; off < sz; off += sizeof(struct dirent)) {
|
||||
if (read(fd, &dirent, sizeof(struct dirent)) != sizeof(struct dirent)) {
|
||||
printf(1, "ls: read error\n");
|
||||
break;
|
||||
printf(1, "ls: read error\n");
|
||||
break;
|
||||
}
|
||||
if (dirent.inum != 0) {
|
||||
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
|
||||
if (stat (dirent.name, &st) < 0) {
|
||||
printf(1, "stat: failed %s\n", dirent.name);
|
||||
continue;
|
||||
}
|
||||
pname(dirent.name);
|
||||
printf(1, "%d %d %d\n", st.st_type, dirent.inum, st.st_size);
|
||||
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
|
||||
if (stat (dirent.name, &st) < 0) {
|
||||
printf(1, "stat: failed %s\n", dirent.name);
|
||||
continue;
|
||||
}
|
||||
pname(dirent.name);
|
||||
printf(1, "%d %d %d\n", st.st_type, dirent.inum, st.st_size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
2
main.c
2
main.c
|
@ -97,7 +97,7 @@ mpmain(void)
|
|||
// make sure there's a TSS
|
||||
setupsegs(0);
|
||||
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
cpus[cpu()].booted = 1;
|
||||
|
||||
// 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;
|
||||
freeblock = usedblocks;
|
||||
|
||||
printf ("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,
|
||||
bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks);
|
||||
printf("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,
|
||||
bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks);
|
||||
|
||||
assert (nblocks + usedblocks == size);
|
||||
|
||||
|
@ -246,22 +246,22 @@ iappend(uint inum, void *xp, int n)
|
|||
assert(fbn < MAXFILE);
|
||||
if (fbn < NDIRECT) {
|
||||
if(xint(din.addrs[fbn]) == 0) {
|
||||
din.addrs[fbn] = xint(freeblock++);
|
||||
usedblocks++;
|
||||
din.addrs[fbn] = xint(freeblock++);
|
||||
usedblocks++;
|
||||
}
|
||||
x = xint(din.addrs[fbn]);
|
||||
} else {
|
||||
if(xint(din.addrs[INDIRECT]) == 0) {
|
||||
printf("allocate indirect block\n");
|
||||
din.addrs[INDIRECT] = xint(freeblock++);
|
||||
usedblocks++;
|
||||
printf("allocate indirect block\n");
|
||||
din.addrs[INDIRECT] = xint(freeblock++);
|
||||
usedblocks++;
|
||||
}
|
||||
printf("read indirect block\n");
|
||||
rsect(xint(din.addrs[INDIRECT]), (char *) indirect);
|
||||
if (indirect[fbn - NDIRECT] == 0) {
|
||||
indirect[fbn - NDIRECT] = xint(freeblock++);
|
||||
usedblocks++;
|
||||
wsect(xint(din.addrs[INDIRECT]), (char *) indirect);
|
||||
indirect[fbn - NDIRECT] = xint(freeblock++);
|
||||
usedblocks++;
|
||||
wsect(xint(din.addrs[INDIRECT]), (char *) indirect);
|
||||
}
|
||||
x = xint(indirect[fbn-NDIRECT]);
|
||||
}
|
||||
|
|
236
mmu.h
236
mmu.h
|
@ -3,133 +3,133 @@
|
|||
*/
|
||||
|
||||
// Eflags register
|
||||
#define FL_CF 0x00000001 // Carry Flag
|
||||
#define FL_PF 0x00000004 // Parity Flag
|
||||
#define FL_AF 0x00000010 // Auxiliary carry Flag
|
||||
#define FL_ZF 0x00000040 // Zero Flag
|
||||
#define FL_SF 0x00000080 // Sign Flag
|
||||
#define FL_TF 0x00000100 // Trap Flag
|
||||
#define FL_IF 0x00000200 // Interrupt Flag
|
||||
#define FL_DF 0x00000400 // Direction Flag
|
||||
#define FL_OF 0x00000800 // Overflow Flag
|
||||
#define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask
|
||||
#define FL_IOPL_0 0x00000000 // IOPL == 0
|
||||
#define FL_IOPL_1 0x00001000 // IOPL == 1
|
||||
#define FL_IOPL_2 0x00002000 // IOPL == 2
|
||||
#define FL_IOPL_3 0x00003000 // IOPL == 3
|
||||
#define FL_NT 0x00004000 // Nested Task
|
||||
#define FL_RF 0x00010000 // Resume Flag
|
||||
#define FL_VM 0x00020000 // Virtual 8086 mode
|
||||
#define FL_AC 0x00040000 // Alignment Check
|
||||
#define FL_VIF 0x00080000 // Virtual Interrupt Flag
|
||||
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
|
||||
#define FL_ID 0x00200000 // ID flag
|
||||
#define FL_CF 0x00000001 // Carry Flag
|
||||
#define FL_PF 0x00000004 // Parity Flag
|
||||
#define FL_AF 0x00000010 // Auxiliary carry Flag
|
||||
#define FL_ZF 0x00000040 // Zero Flag
|
||||
#define FL_SF 0x00000080 // Sign Flag
|
||||
#define FL_TF 0x00000100 // Trap Flag
|
||||
#define FL_IF 0x00000200 // Interrupt Flag
|
||||
#define FL_DF 0x00000400 // Direction Flag
|
||||
#define FL_OF 0x00000800 // Overflow Flag
|
||||
#define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask
|
||||
#define FL_IOPL_0 0x00000000 // IOPL == 0
|
||||
#define FL_IOPL_1 0x00001000 // IOPL == 1
|
||||
#define FL_IOPL_2 0x00002000 // IOPL == 2
|
||||
#define FL_IOPL_3 0x00003000 // IOPL == 3
|
||||
#define FL_NT 0x00004000 // Nested Task
|
||||
#define FL_RF 0x00010000 // Resume Flag
|
||||
#define FL_VM 0x00020000 // Virtual 8086 mode
|
||||
#define FL_AC 0x00040000 // Alignment Check
|
||||
#define FL_VIF 0x00080000 // Virtual Interrupt Flag
|
||||
#define FL_VIP 0x00100000 // Virtual Interrupt Pending
|
||||
#define FL_ID 0x00200000 // ID flag
|
||||
|
||||
// Segment Descriptor
|
||||
struct segdesc {
|
||||
uint lim_15_0 : 16; // Low bits of segment limit
|
||||
uint base_15_0 : 16; // Low 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 s : 1; // 0 = system, 1 = application
|
||||
uint dpl : 2; // Descriptor Privilege Level
|
||||
uint p : 1; // Present
|
||||
uint lim_19_16 : 4; // High bits of segment limit
|
||||
uint avl : 1; // Unused (available for software use)
|
||||
uint rsv1 : 1; // Reserved
|
||||
uint db : 1; // 0 = 16-bit segment, 1 = 32-bit segment
|
||||
uint g : 1; // Granularity: limit scaled by 4K when set
|
||||
uint base_31_24 : 8; // High bits of segment base address
|
||||
uint lim_15_0 : 16; // Low bits of segment limit
|
||||
uint base_15_0 : 16; // Low 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 s : 1; // 0 = system, 1 = application
|
||||
uint dpl : 2; // Descriptor Privilege Level
|
||||
uint p : 1; // Present
|
||||
uint lim_19_16 : 4; // High bits of segment limit
|
||||
uint avl : 1; // Unused (available for software use)
|
||||
uint rsv1 : 1; // Reserved
|
||||
uint db : 1; // 0 = 16-bit segment, 1 = 32-bit segment
|
||||
uint g : 1; // Granularity: limit scaled by 4K when set
|
||||
uint base_31_24 : 8; // High bits of segment base address
|
||||
};
|
||||
|
||||
// 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
|
||||
#define SEG(type, base, lim, dpl) (struct segdesc) \
|
||||
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
||||
type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \
|
||||
#define SEG(type, base, lim, dpl) (struct segdesc) \
|
||||
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
||||
type, 1, dpl, 1, (uint) (lim) >> 28, 0, 0, 1, 1, \
|
||||
(uint) (base) >> 24 }
|
||||
|
||||
#define SEG16(type, base, lim, dpl) (struct segdesc) \
|
||||
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
||||
type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \
|
||||
#define SEG16(type, base, lim, dpl) (struct segdesc) \
|
||||
{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \
|
||||
type, 1, dpl, 1, (uint) (lim) >> 16, 0, 0, 1, 0, \
|
||||
(uint) (base) >> 24 }
|
||||
|
||||
// Application segment type bits
|
||||
#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
|
||||
#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
|
||||
|
||||
// System segment type bits
|
||||
#define STS_T16A 0x1 // Available 16-bit TSS
|
||||
#define STS_LDT 0x2 // Local Descriptor Table
|
||||
#define STS_T16B 0x3 // Busy 16-bit TSS
|
||||
#define STS_CG16 0x4 // 16-bit Call Gate
|
||||
#define STS_TG 0x5 // Task Gate / Coum Transmitions
|
||||
#define STS_IG16 0x6 // 16-bit Interrupt Gate
|
||||
#define STS_TG16 0x7 // 16-bit Trap Gate
|
||||
#define STS_T32A 0x9 // Available 32-bit TSS
|
||||
#define STS_T32B 0xB // Busy 32-bit TSS
|
||||
#define STS_CG32 0xC // 32-bit Call Gate
|
||||
#define STS_IG32 0xE // 32-bit Interrupt Gate
|
||||
#define STS_TG32 0xF // 32-bit Trap Gate
|
||||
#define STS_T16A 0x1 // Available 16-bit TSS
|
||||
#define STS_LDT 0x2 // Local Descriptor Table
|
||||
#define STS_T16B 0x3 // Busy 16-bit TSS
|
||||
#define STS_CG16 0x4 // 16-bit Call Gate
|
||||
#define STS_TG 0x5 // Task Gate / Coum Transmitions
|
||||
#define STS_IG16 0x6 // 16-bit Interrupt Gate
|
||||
#define STS_TG16 0x7 // 16-bit Trap Gate
|
||||
#define STS_T32A 0x9 // Available 32-bit TSS
|
||||
#define STS_T32B 0xB // Busy 32-bit TSS
|
||||
#define STS_CG32 0xC // 32-bit Call Gate
|
||||
#define STS_IG32 0xE // 32-bit Interrupt Gate
|
||||
#define STS_TG32 0xF // 32-bit Trap Gate
|
||||
|
||||
// Task state segment format
|
||||
struct taskstate {
|
||||
uint link; // Old ts selector
|
||||
uint esp0; // Stack pointers and segment selectors
|
||||
ushort ss0; // after an increase in privilege level
|
||||
ushort padding1;
|
||||
uint * esp1;
|
||||
ushort ss1;
|
||||
ushort padding2;
|
||||
uint * esp2;
|
||||
ushort ss2;
|
||||
ushort padding3;
|
||||
void * cr3; // Page directory base
|
||||
uint * eip; // Saved state from last task switch
|
||||
uint eflags;
|
||||
uint eax; // More saved state (registers)
|
||||
uint ecx;
|
||||
uint edx;
|
||||
uint ebx;
|
||||
uint * esp;
|
||||
uint * ebp;
|
||||
uint esi;
|
||||
uint edi;
|
||||
ushort es; // Even more saved state (segment selectors)
|
||||
ushort padding4;
|
||||
ushort cs;
|
||||
ushort padding5;
|
||||
ushort ss;
|
||||
ushort padding6;
|
||||
ushort ds;
|
||||
ushort padding7;
|
||||
ushort fs;
|
||||
ushort padding8;
|
||||
ushort gs;
|
||||
ushort padding9;
|
||||
ushort ldt;
|
||||
ushort padding10;
|
||||
ushort t; // Trap on task switch
|
||||
ushort iomb; // I/O map base address
|
||||
uint link; // Old ts selector
|
||||
uint esp0; // Stack pointers and segment selectors
|
||||
ushort ss0; // after an increase in privilege level
|
||||
ushort padding1;
|
||||
uint * esp1;
|
||||
ushort ss1;
|
||||
ushort padding2;
|
||||
uint * esp2;
|
||||
ushort ss2;
|
||||
ushort padding3;
|
||||
void * cr3; // Page directory base
|
||||
uint * eip; // Saved state from last task switch
|
||||
uint eflags;
|
||||
uint eax; // More saved state (registers)
|
||||
uint ecx;
|
||||
uint edx;
|
||||
uint ebx;
|
||||
uint * esp;
|
||||
uint * ebp;
|
||||
uint esi;
|
||||
uint edi;
|
||||
ushort es; // Even more saved state (segment selectors)
|
||||
ushort padding4;
|
||||
ushort cs;
|
||||
ushort padding5;
|
||||
ushort ss;
|
||||
ushort padding6;
|
||||
ushort ds;
|
||||
ushort padding7;
|
||||
ushort fs;
|
||||
ushort padding8;
|
||||
ushort gs;
|
||||
ushort padding9;
|
||||
ushort ldt;
|
||||
ushort padding10;
|
||||
ushort t; // Trap on task switch
|
||||
ushort iomb; // I/O map base address
|
||||
};
|
||||
|
||||
// Gate descriptors for interrupts and traps
|
||||
struct gatedesc {
|
||||
uint off_15_0 : 16; // low 16 bits of offset in segment
|
||||
uint ss : 16; // segment selector
|
||||
uint args : 5; // # args, 0 for interrupt/trap gates
|
||||
uint rsv1 : 3; // reserved(should be zero I guess)
|
||||
uint type : 4; // type(STS_{TG,IG32,TG32})
|
||||
uint s : 1; // must be 0 (system)
|
||||
uint dpl : 2; // descriptor(meaning new) privilege level
|
||||
uint p : 1; // Present
|
||||
uint off_31_16 : 16; // high bits of offset in segment
|
||||
uint off_15_0 : 16; // low 16 bits of offset in segment
|
||||
uint ss : 16; // segment selector
|
||||
uint args : 5; // # args, 0 for interrupt/trap gates
|
||||
uint rsv1 : 3; // reserved(should be zero I guess)
|
||||
uint type : 4; // type(STS_{TG,IG32,TG32})
|
||||
uint s : 1; // must be 0 (system)
|
||||
uint dpl : 2; // descriptor(meaning new) privilege level
|
||||
uint p : 1; // Present
|
||||
uint off_31_16 : 16; // high bits of offset in segment
|
||||
};
|
||||
|
||||
// Set up a normal interrupt/trap gate descriptor.
|
||||
|
@ -138,18 +138,18 @@ struct gatedesc {
|
|||
// - sel: Code segment selector for interrupt/trap handler
|
||||
// - off: Offset in code segment for interrupt/trap handler
|
||||
// - dpl: Descriptor Privilege Level -
|
||||
// the privilege level required for software to invoke
|
||||
// this interrupt/trap gate explicitly using an int instruction.
|
||||
#define SETGATE(gate, istrap, sel, off, d) \
|
||||
{ \
|
||||
(gate).off_15_0 = (uint) (off) & 0xffff; \
|
||||
(gate).ss = (sel); \
|
||||
(gate).args = 0; \
|
||||
(gate).rsv1 = 0; \
|
||||
(gate).type = (istrap) ? STS_TG32 : STS_IG32; \
|
||||
(gate).s = 0; \
|
||||
(gate).dpl = (d); \
|
||||
(gate).p = 1; \
|
||||
(gate).off_31_16 = (uint) (off) >> 16; \
|
||||
// the privilege level required for software to invoke
|
||||
// this interrupt/trap gate explicitly using an int instruction.
|
||||
#define SETGATE(gate, istrap, sel, off, d) \
|
||||
{ \
|
||||
(gate).off_15_0 = (uint) (off) & 0xffff; \
|
||||
(gate).ss = (sel); \
|
||||
(gate).args = 0; \
|
||||
(gate).rsv1 = 0; \
|
||||
(gate).type = (istrap) ? STS_TG32 : STS_IG32; \
|
||||
(gate).s = 0; \
|
||||
(gate).dpl = (d); \
|
||||
(gate).p = 1; \
|
||||
(gate).off_31_16 = (uint) (off) >> 16; \
|
||||
}
|
||||
|
||||
|
|
58
mp.c
58
mp.c
|
@ -8,25 +8,25 @@
|
|||
#include "proc.h"
|
||||
|
||||
static char* buses[] = {
|
||||
"CBUSI ",
|
||||
"CBUSII",
|
||||
"EISA ",
|
||||
"FUTURE",
|
||||
"INTERN",
|
||||
"ISA ",
|
||||
"MBI ",
|
||||
"MBII ",
|
||||
"MCA ",
|
||||
"MPI ",
|
||||
"MPSA ",
|
||||
"NUBUS ",
|
||||
"PCI ",
|
||||
"PCMCIA",
|
||||
"TC ",
|
||||
"VL ",
|
||||
"VME ",
|
||||
"XPRESS",
|
||||
0,
|
||||
"CBUSI ",
|
||||
"CBUSII",
|
||||
"EISA ",
|
||||
"FUTURE",
|
||||
"INTERN",
|
||||
"ISA ",
|
||||
"MBI ",
|
||||
"MBII ",
|
||||
"MCA ",
|
||||
"MPI ",
|
||||
"MPSA ",
|
||||
"NUBUS ",
|
||||
"PCI ",
|
||||
"PCMCIA",
|
||||
"TC ",
|
||||
"VL ",
|
||||
"VME ",
|
||||
"XPRESS",
|
||||
0,
|
||||
};
|
||||
|
||||
struct cpu cpus[NCPU];
|
||||
|
@ -146,7 +146,7 @@ mp_init(void)
|
|||
proc = (struct mppe *) p;
|
||||
cpus[ncpu].apicid = proc->apicid;
|
||||
if (proc->flags & MPBP) {
|
||||
bcpu = &cpus[ncpu];
|
||||
bcpu = &cpus[ncpu];
|
||||
}
|
||||
ncpu++;
|
||||
p += sizeof(struct mppe);
|
||||
|
@ -154,8 +154,8 @@ mp_init(void)
|
|||
case MPBUS:
|
||||
bus = (struct mpbe *) p;
|
||||
for(i = 0; buses[i]; i++){
|
||||
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
|
||||
break;
|
||||
if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
|
||||
break;
|
||||
}
|
||||
p += sizeof(struct mpbe);
|
||||
continue;
|
||||
|
@ -171,18 +171,18 @@ mp_init(void)
|
|||
default:
|
||||
cprintf("mpinit: unknown PCMP type 0x%x (e-p 0x%x)\n", *p, e-p);
|
||||
while(p < e){
|
||||
cprintf("%uX ", *p);
|
||||
p++;
|
||||
cprintf("%uX ", *p);
|
||||
p++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mp->imcrp) { // it appears that bochs doesn't support IMCR, and code won't run
|
||||
outb(0x22, 0x70); /* select IMCR */
|
||||
byte = inb(0x23); /* current contents */
|
||||
byte |= 0x01; /* mask external INTR */
|
||||
outb(0x23, byte); /* disconnect 8259s/NMI */
|
||||
outb(0x22, 0x70); /* select IMCR */
|
||||
byte = inb(0x23); /* current contents */
|
||||
byte |= 0x01; /* mask external INTR */
|
||||
outb(0x23, byte); /* disconnect 8259s/NMI */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ mp_startthem(void)
|
|||
int c;
|
||||
|
||||
memmove((void *) APBOOTCODE,_binary_bootother_start,
|
||||
(uint) _binary_bootother_size);
|
||||
(uint) _binary_bootother_size);
|
||||
|
||||
for(c = 0; c < ncpu; c++){
|
||||
if (c == cpu()) continue;
|
||||
|
|
170
mp.h
170
mp.h
|
@ -3,121 +3,121 @@
|
|||
*
|
||||
*/
|
||||
|
||||
struct mp { /* floating pointer */
|
||||
uchar signature[4]; /* "_MP_" */
|
||||
void* physaddr; /* physical address of MP configuration table */
|
||||
uchar length; /* 1 */
|
||||
uchar specrev; /* [14] */
|
||||
uchar checksum; /* all bytes must add up to 0 */
|
||||
uchar type; /* MP system configuration type */
|
||||
struct mp { /* floating pointer */
|
||||
uchar signature[4]; /* "_MP_" */
|
||||
void* physaddr; /* physical address of MP configuration table */
|
||||
uchar length; /* 1 */
|
||||
uchar specrev; /* [14] */
|
||||
uchar checksum; /* all bytes must add up to 0 */
|
||||
uchar type; /* MP system configuration type */
|
||||
uchar imcrp;
|
||||
uchar reserved[3];
|
||||
};
|
||||
|
||||
struct mpctb { /* configuration table header */
|
||||
uchar signature[4]; /* "PCMP" */
|
||||
ushort length; /* total table length */
|
||||
uchar version; /* [14] */
|
||||
uchar checksum; /* all bytes must add up to 0 */
|
||||
uchar product[20]; /* product id */
|
||||
uint * oemtable; /* OEM table pointer */
|
||||
ushort oemlength; /* OEM table length */
|
||||
ushort entry; /* entry count */
|
||||
uint * lapicaddr; /* address of local APIC */
|
||||
ushort xlength; /* extended table length */
|
||||
uchar xchecksum; /* extended table checksum */
|
||||
struct mpctb { /* configuration table header */
|
||||
uchar signature[4]; /* "PCMP" */
|
||||
ushort length; /* total table length */
|
||||
uchar version; /* [14] */
|
||||
uchar checksum; /* all bytes must add up to 0 */
|
||||
uchar product[20]; /* product id */
|
||||
uint * oemtable; /* OEM table pointer */
|
||||
ushort oemlength; /* OEM table length */
|
||||
ushort entry; /* entry count */
|
||||
uint * lapicaddr; /* address of local APIC */
|
||||
ushort xlength; /* extended table length */
|
||||
uchar xchecksum; /* extended table checksum */
|
||||
uchar reserved;
|
||||
};
|
||||
|
||||
struct mppe { /* processor table entry */
|
||||
uchar type; /* entry type (0) */
|
||||
uchar apicid; /* local APIC id */
|
||||
uchar version; /* local APIC verison */
|
||||
uchar flags; /* CPU flags */
|
||||
uchar signature[4]; /* CPU signature */
|
||||
uint feature; /* feature flags from CPUID instruction */
|
||||
struct mppe { /* processor table entry */
|
||||
uchar type; /* entry type (0) */
|
||||
uchar apicid; /* local APIC id */
|
||||
uchar version; /* local APIC verison */
|
||||
uchar flags; /* CPU flags */
|
||||
uchar signature[4]; /* CPU signature */
|
||||
uint feature; /* feature flags from CPUID instruction */
|
||||
uchar reserved[8];
|
||||
};
|
||||
|
||||
struct mpbe { /* bus table entry */
|
||||
uchar type; /* entry type (1) */
|
||||
uchar busno; /* bus id */
|
||||
char string[6]; /* bus type string */
|
||||
struct mpbe { /* bus table entry */
|
||||
uchar type; /* entry type (1) */
|
||||
uchar busno; /* bus id */
|
||||
char string[6]; /* bus type string */
|
||||
};
|
||||
|
||||
struct mpioapic { /* I/O APIC table entry */
|
||||
uchar type; /* entry type (2) */
|
||||
uchar apicno; /* I/O APIC id */
|
||||
uchar version; /* I/O APIC version */
|
||||
uchar flags; /* I/O APIC flags */
|
||||
uint * addr; /* I/O APIC address */
|
||||
struct mpioapic { /* I/O APIC table entry */
|
||||
uchar type; /* entry type (2) */
|
||||
uchar apicno; /* I/O APIC id */
|
||||
uchar version; /* I/O APIC version */
|
||||
uchar flags; /* I/O APIC flags */
|
||||
uint * addr; /* I/O APIC address */
|
||||
};
|
||||
|
||||
struct mpie { /* interrupt table entry */
|
||||
uchar type; /* entry type ([34]) */
|
||||
uchar intr; /* interrupt type */
|
||||
ushort flags; /* interrupt flag */
|
||||
uchar busno; /* source bus id */
|
||||
uchar irq; /* source bus irq */
|
||||
uchar apicno; /* destination APIC id */
|
||||
uchar intin; /* destination APIC [L]INTIN# */
|
||||
struct mpie { /* interrupt table entry */
|
||||
uchar type; /* entry type ([34]) */
|
||||
uchar intr; /* interrupt type */
|
||||
ushort flags; /* interrupt flag */
|
||||
uchar busno; /* source bus id */
|
||||
uchar irq; /* source bus irq */
|
||||
uchar apicno; /* destination APIC id */
|
||||
uchar intin; /* destination APIC [L]INTIN# */
|
||||
};
|
||||
|
||||
enum { /* table entry types */
|
||||
MPPROCESSOR = 0x00, /* one entry per processor */
|
||||
MPBUS = 0x01, /* one entry per bus */
|
||||
MPIOAPIC = 0x02, /* one entry per I/O APIC */
|
||||
MPIOINTR = 0x03, /* one entry per bus interrupt source */
|
||||
MPLINTR = 0x04, /* one entry per system interrupt source */
|
||||
enum { /* table entry types */
|
||||
MPPROCESSOR = 0x00, /* one entry per processor */
|
||||
MPBUS = 0x01, /* one entry per bus */
|
||||
MPIOAPIC = 0x02, /* one entry per I/O APIC */
|
||||
MPIOINTR = 0x03, /* one entry per bus interrupt source */
|
||||
MPLINTR = 0x04, /* one entry per system interrupt source */
|
||||
|
||||
MPSASM = 0x80,
|
||||
MPHIERARCHY = 0x81,
|
||||
MPHIERARCHY = 0x81,
|
||||
MPCBASM = 0x82,
|
||||
|
||||
/* PCMPprocessor and PCMPioapic flags */
|
||||
MPEN = 0x01, /* enabled */
|
||||
MPBP = 0x02, /* bootstrap processor */
|
||||
MPEN = 0x01, /* enabled */
|
||||
MPBP = 0x02, /* bootstrap processor */
|
||||
|
||||
/* PCMPiointr and PCMPlintr flags */
|
||||
MPPOMASK = 0x03, /* polarity conforms to specifications of bus */
|
||||
MPHIGH = 0x01, /* active high */
|
||||
MPLOW = 0x03, /* active low */
|
||||
MPELMASK = 0x0C, /* trigger mode of APIC input signals */
|
||||
MPEDGE = 0x04, /* edge-triggered */
|
||||
MPLEVEL = 0x0C, /* level-triggered */
|
||||
/* PCMPiointr and PCMPlintr flags */
|
||||
MPPOMASK = 0x03, /* polarity conforms to specifications of bus */
|
||||
MPHIGH = 0x01, /* active high */
|
||||
MPLOW = 0x03, /* active low */
|
||||
MPELMASK = 0x0C, /* trigger mode of APIC input signals */
|
||||
MPEDGE = 0x04, /* edge-triggered */
|
||||
MPLEVEL = 0x0C, /* level-triggered */
|
||||
|
||||
/* PCMPiointr and PCMPlintr interrupt type */
|
||||
MPINT = 0x00, /* vectored interrupt from APIC Rdt */
|
||||
MPNMI = 0x01, /* non-maskable interrupt */
|
||||
MPSMI = 0x02, /* system management interrupt */
|
||||
MPExtINT = 0x03, /* vectored interrupt from external PIC */
|
||||
MPINT = 0x00, /* vectored interrupt from APIC Rdt */
|
||||
MPNMI = 0x01, /* non-maskable interrupt */
|
||||
MPSMI = 0x02, /* system management interrupt */
|
||||
MPExtINT = 0x03, /* vectored interrupt from external PIC */
|
||||
};
|
||||
|
||||
/*
|
||||
* Common bits for
|
||||
* I/O APIC Redirection Table Entry;
|
||||
* Local APIC Local Interrupt Vector Table;
|
||||
* Local APIC Inter-Processor Interrupt;
|
||||
* Local APIC Timer Vector Table.
|
||||
* I/O APIC Redirection Table Entry;
|
||||
* Local APIC Local Interrupt Vector Table;
|
||||
* Local APIC Inter-Processor Interrupt;
|
||||
* Local APIC Timer Vector Table.
|
||||
*/
|
||||
enum {
|
||||
APIC_FIXED = 0x00000000, /* [10:8] Delivery Mode */
|
||||
APIC_LOWEST = 0x00000100, /* Lowest priority */
|
||||
APIC_SMI = 0x00000200, /* System Management Interrupt */
|
||||
APIC_RR = 0x00000300, /* Remote Read */
|
||||
APIC_NMI = 0x00000400,
|
||||
APIC_INIT = 0x00000500, /* INIT/RESET */
|
||||
APIC_STARTUP = 0x00000600, /* Startup IPI */
|
||||
APIC_EXTINT = 0x00000700,
|
||||
APIC_FIXED = 0x00000000, /* [10:8] Delivery Mode */
|
||||
APIC_LOWEST = 0x00000100, /* Lowest priority */
|
||||
APIC_SMI = 0x00000200, /* System Management Interrupt */
|
||||
APIC_RR = 0x00000300, /* Remote Read */
|
||||
APIC_NMI = 0x00000400,
|
||||
APIC_INIT = 0x00000500, /* INIT/RESET */
|
||||
APIC_STARTUP = 0x00000600, /* Startup IPI */
|
||||
APIC_EXTINT = 0x00000700,
|
||||
|
||||
APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */
|
||||
APIC_LOGICAL = 0x00000800,
|
||||
APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */
|
||||
APIC_LOGICAL = 0x00000800,
|
||||
|
||||
APIC_DELIVS = 0x00001000, /* [12] Delivery Status (RO) */
|
||||
APIC_HIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */
|
||||
APIC_LOW = 0x00002000,
|
||||
APIC_REMOTEIRR = 0x00004000, /* [14] Remote IRR (RO) */
|
||||
APIC_EDGE = 0x00000000, /* [15] Trigger Mode (RW) */
|
||||
APIC_LEVEL = 0x00008000,
|
||||
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */
|
||||
APIC_DELIVS = 0x00001000, /* [12] Delivery Status (RO) */
|
||||
APIC_HIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */
|
||||
APIC_LOW = 0x00002000,
|
||||
APIC_REMOTEIRR = 0x00004000, /* [14] Remote IRR (RO) */
|
||||
APIC_EDGE = 0x00000000, /* [15] Trigger Mode (RW) */
|
||||
APIC_LEVEL = 0x00008000,
|
||||
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */
|
||||
};
|
||||
|
|
18
picirq.c
18
picirq.c
|
@ -4,10 +4,10 @@
|
|||
#include "defs.h"
|
||||
|
||||
// I/O Addresses of the two 8259A programmable interrupt controllers
|
||||
#define IO_PIC1 0x20 // Master (IRQs 0-7)
|
||||
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
|
||||
#define IO_PIC1 0x20 // Master (IRQs 0-7)
|
||||
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
|
||||
|
||||
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
|
||||
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
|
||||
|
||||
// Current IRQ mask.
|
||||
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
|
||||
|
@ -49,19 +49,19 @@ pic_init(void)
|
|||
// n: 1 = special fully nested mode
|
||||
// b: 1 = buffered mode
|
||||
// m: 0 = slave PIC, 1 = master PIC
|
||||
// (ignored when b is 0, as the master/slave role
|
||||
// can be hardwired).
|
||||
// (ignored when b is 0, as the master/slave role
|
||||
// can be hardwired).
|
||||
// a: 1 = Automatic EOI mode
|
||||
// p: 0 = MCS-80/85 mode, 1 = intel x86 mode
|
||||
outb(IO_PIC1+1, 0x3);
|
||||
|
||||
// Set up slave (8259A-2)
|
||||
outb(IO_PIC2, 0x11); // ICW1
|
||||
outb(IO_PIC2+1, IRQ_OFFSET + 8); // ICW2
|
||||
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
|
||||
outb(IO_PIC2, 0x11); // ICW1
|
||||
outb(IO_PIC2+1, IRQ_OFFSET + 8); // ICW2
|
||||
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
|
||||
// NB Automatic EOI mode doesn't tend to work on the slave.
|
||||
// Linux source code says it's "to be investigated".
|
||||
outb(IO_PIC2+1, 0x3); // ICW4
|
||||
outb(IO_PIC2+1, 0x3); // ICW4
|
||||
|
||||
// OCW3: 0ef01prs
|
||||
// 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++;
|
||||
}
|
||||
} else if(c == 'c'){
|
||||
putc(fd, *ap);
|
||||
ap++;
|
||||
putc(fd, *ap);
|
||||
ap++;
|
||||
} else if(c == '%'){
|
||||
putc(fd, c);
|
||||
} else {
|
||||
|
|
58
setjmp.S
58
setjmp.S
|
@ -1,37 +1,35 @@
|
|||
.globl setjmp
|
||||
setjmp:
|
||||
movl 4(%esp), %eax
|
||||
|
||||
movl %ebx, 0(%eax)
|
||||
movl %ecx, 4(%eax)
|
||||
movl %edx, 8(%eax)
|
||||
movl %esi, 12(%eax)
|
||||
movl %edi, 16(%eax)
|
||||
movl %esp, 20(%eax)
|
||||
movl %ebp, 24(%eax)
|
||||
pushl 0(%esp) /* %eip */
|
||||
popl 28(%eax)
|
||||
|
||||
movl $0, %eax /* return value */
|
||||
ret
|
||||
movl 4(%esp), %eax
|
||||
|
||||
movl %ebx, 0(%eax)
|
||||
movl %ecx, 4(%eax)
|
||||
movl %edx, 8(%eax)
|
||||
movl %esi, 12(%eax)
|
||||
movl %edi, 16(%eax)
|
||||
movl %esp, 20(%eax)
|
||||
movl %ebp, 24(%eax)
|
||||
pushl 0(%esp) /* %eip */
|
||||
popl 28(%eax)
|
||||
|
||||
movl $0, %eax /* return value */
|
||||
ret
|
||||
|
||||
.globl longjmp
|
||||
longjmp:
|
||||
movl 4(%esp), %eax
|
||||
|
||||
movl 0(%eax), %ebx
|
||||
movl 4(%eax), %ecx
|
||||
movl 8(%eax), %edx
|
||||
movl 12(%eax), %esi
|
||||
movl 16(%eax), %edi
|
||||
movl 20(%eax), %esp
|
||||
movl 24(%eax), %ebp
|
||||
movl 4(%esp), %eax
|
||||
|
||||
movl 0(%eax), %ebx
|
||||
movl 4(%eax), %ecx
|
||||
movl 8(%eax), %edx
|
||||
movl 12(%eax), %esi
|
||||
movl 16(%eax), %edi
|
||||
movl 20(%eax), %esp
|
||||
movl 24(%eax), %ebp
|
||||
|
||||
addl $4, %esp /* pop %eip into thin air */
|
||||
pushl 28(%eax) /* push new %eip */
|
||||
|
||||
movl $1, %eax /* return value (appears to come from setjmp!) */
|
||||
ret
|
||||
addl $4, %esp /* pop %eip into thin air */
|
||||
pushl 28(%eax) /* push new %eip */
|
||||
|
||||
movl $1, %eax /* return value (appears to come from setjmp!) */
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
|
124
sh.c
124
sh.c
|
@ -68,28 +68,28 @@ parse(char *s)
|
|||
while (1) {
|
||||
switch ((c = gettoken(0, &t))) {
|
||||
|
||||
case 'w': // Add an argument
|
||||
case 'w': // Add an argument
|
||||
if (cmdlist[nextcmd].argc >= MAXARGS) {
|
||||
printf(2, "too many arguments\n");
|
||||
return -1;
|
||||
printf(2, "too many arguments\n");
|
||||
return -1;
|
||||
}
|
||||
cmdlist[nextcmd].argv[cmdlist[nextcmd].argc++] = t;
|
||||
break;
|
||||
|
||||
case '<': // Input redirection
|
||||
|
||||
case '<': // Input redirection
|
||||
// Grab the filename from the argument list
|
||||
if (gettoken(0, &t) != 'w') {
|
||||
printf(2, "syntax error: < not followed by word\n");
|
||||
return -1;
|
||||
printf(2, "syntax error: < not followed by word\n");
|
||||
return -1;
|
||||
}
|
||||
addio('<', t);
|
||||
break;
|
||||
|
||||
case '>': // Output redirection
|
||||
|
||||
case '>': // Output redirection
|
||||
// Grab the filename from the argument list
|
||||
if (gettoken(0, &t) != 'w') {
|
||||
printf(2, "syntax error: > not followed by word\n");
|
||||
return -1;
|
||||
printf(2, "syntax error: > not followed by word\n");
|
||||
return -1;
|
||||
}
|
||||
addio('>', t);
|
||||
break;
|
||||
|
@ -100,13 +100,13 @@ parse(char *s)
|
|||
nextcmd++;
|
||||
break;
|
||||
|
||||
case 0: // String is complete
|
||||
case 0: // String is complete
|
||||
return 0;
|
||||
|
||||
|
||||
default:
|
||||
printf(2, "syntax error: bad return %d from gettoken", c);
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,14 +136,14 @@ runcmd(void)
|
|||
cmdlist[c].argv[0] = cmdlist[c].argv0buf;
|
||||
}
|
||||
cmdlist[c].argv[cmdlist[c].argc] = 0;
|
||||
|
||||
|
||||
// Print the command.
|
||||
if (debug) {
|
||||
printf(2, "[%d] SPAWN:", getpid());
|
||||
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++) {
|
||||
printf(2, "%c %s", iolist[i].token, iolist[i].s);
|
||||
printf(2, "%c %s", iolist[i].token, iolist[i].s);
|
||||
}
|
||||
printf(2, "\n");
|
||||
}
|
||||
|
@ -156,55 +156,55 @@ runcmd(void)
|
|||
|
||||
if (cmdlist[c].token == '|')
|
||||
if (pipe(fdarray) < 0)
|
||||
printf(2, "cmd %d pipe failed\n", c);
|
||||
printf(2, "cmd %d pipe failed\n", c);
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
if (cmdlist[c].token == '|') {
|
||||
if (close(1) < 0)
|
||||
printf(2, "close 1 failed\n");
|
||||
if ((tfd = dup(fdarray[1])) < 0)
|
||||
printf(2, "dup failed\n");
|
||||
if (close(fdarray[0]) < 0)
|
||||
printf(2, "close fdarray[0] failed\n");
|
||||
if (close(fdarray[1]) < 0)
|
||||
printf(2, "close fdarray[1] failed\n");
|
||||
if (close(1) < 0)
|
||||
printf(2, "close 1 failed\n");
|
||||
if ((tfd = dup(fdarray[1])) < 0)
|
||||
printf(2, "dup failed\n");
|
||||
if (close(fdarray[0]) < 0)
|
||||
printf(2, "close fdarray[0] failed\n");
|
||||
if (close(fdarray[1]) < 0)
|
||||
printf(2, "close fdarray[1] failed\n");
|
||||
}
|
||||
if (c > 0 && cmdlist[c-1].token == '|') {
|
||||
if (close(0) < 0)
|
||||
printf(2, "close 0 failed\n");
|
||||
if ((tfd = dup(fdarray[0])) < 0)
|
||||
printf(2, "dup failed\n");
|
||||
if (close(fdarray[0]) < 0)
|
||||
printf(2, "close fdarray[0] failed\n");
|
||||
if (close(fdarray[1]) < 0)
|
||||
printf(2, "close fdarray[1] failed\n");
|
||||
if (close(0) < 0)
|
||||
printf(2, "close 0 failed\n");
|
||||
if ((tfd = dup(fdarray[0])) < 0)
|
||||
printf(2, "dup failed\n");
|
||||
if (close(fdarray[0]) < 0)
|
||||
printf(2, "close fdarray[0] failed\n");
|
||||
if (close(fdarray[1]) < 0)
|
||||
printf(2, "close fdarray[1] failed\n");
|
||||
}
|
||||
if (ioredirection() < 0)
|
||||
exit();
|
||||
exit();
|
||||
if ((r = exec(cmdlist[c].argv0buf, (char**) cmdlist[c].argv)) < 0) {
|
||||
printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r);
|
||||
exit();
|
||||
printf(2, "exec %s: %d\n", cmdlist[c].argv[0], r);
|
||||
exit();
|
||||
}
|
||||
} else if (pid > 0) {
|
||||
int p;
|
||||
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 == '|') {
|
||||
close(fdarray[0]);
|
||||
close(fdarray[1]);
|
||||
close(fdarray[0]);
|
||||
close(fdarray[1]);
|
||||
}
|
||||
if (cmdlist[c].token != '|') {
|
||||
if (debug)
|
||||
printf(2, "[%d] WAIT for children\n", getpid());
|
||||
do {
|
||||
p = wait();
|
||||
if (debug)
|
||||
printf(2, "[%d] WAIT child %d finished\n", getpid(), p);
|
||||
} while (p > 0);
|
||||
if (debug)
|
||||
printf(2, "[%d] wait finished\n", getpid());
|
||||
if (debug)
|
||||
printf(2, "[%d] WAIT for children\n", getpid());
|
||||
do {
|
||||
p = wait();
|
||||
if (debug)
|
||||
printf(2, "[%d] WAIT child %d finished\n", getpid(), p);
|
||||
} while (p > 0);
|
||||
if (debug)
|
||||
printf(2, "[%d] wait finished\n", getpid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,23 +219,23 @@ ioredirection(void)
|
|||
switch (iolist[i].token) {
|
||||
case '<':
|
||||
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) {
|
||||
printf(2, "failed to open %s for read: %d", iolist[i].s, fd);
|
||||
return -1;
|
||||
printf(2, "failed to open %s for read: %d", iolist[i].s, fd);
|
||||
return -1;
|
||||
}
|
||||
if (debug)
|
||||
printf(2, "redirect 0 from %s\n", iolist[i].s);
|
||||
printf(2, "redirect 0 from %s\n", iolist[i].s);
|
||||
break;
|
||||
case '>':
|
||||
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) {
|
||||
printf(2, "failed to open %s for write: %d", iolist[i].s, fd);
|
||||
exit();
|
||||
printf(2, "failed to open %s for write: %d", iolist[i].s, fd);
|
||||
exit();
|
||||
}
|
||||
if (debug)
|
||||
printf(2, "redirect 1 to %s\n", iolist[i].s);
|
||||
printf(2, "redirect 1 to %s\n", iolist[i].s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -283,11 +283,11 @@ gettoken(char *s, char **p1)
|
|||
// Get the next token from string s.
|
||||
// Set *p1 to the beginning of the token and *p2 just past the token.
|
||||
// Returns
|
||||
// 0 for end-of-string;
|
||||
// < for <;
|
||||
// > for >;
|
||||
// | for |;
|
||||
// w for a word.
|
||||
// 0 for end-of-string;
|
||||
// < for <;
|
||||
// > for >;
|
||||
// | for |;
|
||||
// w for a word.
|
||||
//
|
||||
// Eventually (once we parse the space where the \0 will go),
|
||||
// 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);
|
||||
|
||||
if($n > 510){
|
||||
print STDERR "boot block too large: $n bytes (max 510)\n";
|
||||
exit 1;
|
||||
print STDERR "boot block too large: $n bytes (max 510)\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
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)
|
||||
;
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
getcallerpcs(&lock, lock->pcs);
|
||||
lock->cpu = cpu() + 10;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ release(struct spinlock * lock)
|
|||
|
||||
lock->pcs[0] = 0;
|
||||
lock->cpu = 0xffffffff;
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
cpuid(0, 0, 0, 0, 0); // memory barrier
|
||||
lock->locked = 0;
|
||||
if(--cpus[cpu()].nlock == 0)
|
||||
sti();
|
||||
|
|
14
string.c
14
string.c
|
@ -32,7 +32,7 @@ memmove(void *dst, const void *src, uint n)
|
|||
{
|
||||
const char *s;
|
||||
char *d;
|
||||
|
||||
|
||||
s = src;
|
||||
d = dst;
|
||||
if (s < d && s + n > d) {
|
||||
|
@ -50,10 +50,10 @@ memmove(void *dst, const void *src, uint n)
|
|||
int
|
||||
strncmp(const char *p, const char *q, uint n)
|
||||
{
|
||||
while (n > 0 && *p && *p == *q)
|
||||
n--, p++, q++;
|
||||
if (n == 0)
|
||||
return 0;
|
||||
else
|
||||
return (int) ((uchar) *p - (uchar) *q);
|
||||
while (n > 0 && *p && *p == *q)
|
||||
n--, p++, q++;
|
||||
if (n == 0)
|
||||
return 0;
|
||||
else
|
||||
return (int) ((uchar) *p - (uchar) *q);
|
||||
}
|
||||
|
|
2
trap.c
2
trap.c
|
@ -86,7 +86,7 @@ trap(struct trapframe *tf)
|
|||
|
||||
if(curproc[cpu()]) {
|
||||
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();
|
||||
}
|
||||
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 trapret1
|
||||
|
||||
.globl alltraps
|
||||
alltraps:
|
||||
/* vectors.S sends all traps here */
|
||||
pushl %ds # build
|
||||
pushl %es # trap
|
||||
pushal # frame
|
||||
movl $16,%eax # SEG_KDATA << 3
|
||||
movw %ax,%ds # kernel
|
||||
movw %ax,%es # segments
|
||||
pushl %esp # pass pointer to this trapframe
|
||||
call trap # and call trap()
|
||||
addl $4, %esp
|
||||
# return falls through to trapret...
|
||||
|
||||
/*
|
||||
* a forked process RETs here
|
||||
* expects ESP to point to a Trapframe
|
||||
*/
|
||||
/* vectors.S sends all traps here */
|
||||
pushl %ds # build
|
||||
pushl %es # trap
|
||||
pushal # frame
|
||||
movl $16,%eax # SEG_KDATA << 3
|
||||
movw %ax,%ds # kernel
|
||||
movw %ax,%es # segments
|
||||
pushl %esp # pass pointer to this trapframe
|
||||
call trap # and call trap()
|
||||
addl $4, %esp
|
||||
# return falls through to trapret...
|
||||
|
||||
/*
|
||||
* a forked process RETs here
|
||||
* expects ESP to point to a Trapframe
|
||||
*/
|
||||
.globl trapret
|
||||
trapret:
|
||||
popal
|
||||
popl %es
|
||||
popl %ds
|
||||
addl $0x8, %esp /* trapno and errcode */
|
||||
iret
|
||||
popal
|
||||
popl %es
|
||||
popl %ds
|
||||
addl $0x8, %esp /* trapno and errcode */
|
||||
iret
|
||||
|
||||
.globl forkret1
|
||||
forkret1:
|
||||
movl 4(%esp), %esp
|
||||
jmp trapret
|
||||
|
||||
.globl acpu
|
||||
movl 4(%esp), %esp
|
||||
jmp trapret
|
||||
|
||||
.globl acpu
|
||||
acpu:
|
||||
.long 0
|
||||
.long 0
|
||||
|
|
48
traps.h
48
traps.h
|
@ -1,33 +1,33 @@
|
|||
// system defined:
|
||||
#define T_DIVIDE 0 // divide error
|
||||
#define T_DEBUG 1 // debug exception
|
||||
#define T_NMI 2 // non-maskable interrupt
|
||||
#define T_BRKPT 3 // breakpoint
|
||||
#define T_OFLOW 4 // overflow
|
||||
#define T_BOUND 5 // bounds check
|
||||
#define T_ILLOP 6 // illegal opcode
|
||||
#define T_DEVICE 7 // device not available
|
||||
#define T_DBLFLT 8 // double fault
|
||||
/* #define T_COPROC 9 */ // reserved (not generated by recent processors)
|
||||
#define T_TSS 10 // invalid task switch segment
|
||||
#define T_SEGNP 11 // segment not present
|
||||
#define T_STACK 12 // stack exception
|
||||
#define T_GPFLT 13 // genernal protection fault
|
||||
#define T_PGFLT 14 // page fault
|
||||
/* #define T_RES 15 */ // reserved
|
||||
#define T_FPERR 16 // floating point error
|
||||
#define T_ALIGN 17 // aligment check
|
||||
#define T_MCHK 18 // machine check
|
||||
#define T_SIMDERR 19 // SIMD floating point error
|
||||
#define T_DIVIDE 0 // divide error
|
||||
#define T_DEBUG 1 // debug exception
|
||||
#define T_NMI 2 // non-maskable interrupt
|
||||
#define T_BRKPT 3 // breakpoint
|
||||
#define T_OFLOW 4 // overflow
|
||||
#define T_BOUND 5 // bounds check
|
||||
#define T_ILLOP 6 // illegal opcode
|
||||
#define T_DEVICE 7 // device not available
|
||||
#define T_DBLFLT 8 // double fault
|
||||
/* #define T_COPROC 9 */ // reserved (not generated by recent processors)
|
||||
#define T_TSS 10 // invalid task switch segment
|
||||
#define T_SEGNP 11 // segment not present
|
||||
#define T_STACK 12 // stack exception
|
||||
#define T_GPFLT 13 // genernal protection fault
|
||||
#define T_PGFLT 14 // page fault
|
||||
/* #define T_RES 15 */ // reserved
|
||||
#define T_FPERR 16 // floating point error
|
||||
#define T_ALIGN 17 // aligment check
|
||||
#define T_MCHK 18 // machine check
|
||||
#define T_SIMDERR 19 // SIMD floating point error
|
||||
|
||||
// These are arbitrarily chosen, but with care not to overlap
|
||||
// processor defined exceptions or interrupt vectors.
|
||||
#define T_SYSCALL 48 // system call
|
||||
#define T_DEFAULT 500 // catchall
|
||||
#define T_SYSCALL 48 // system call
|
||||
#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_TIMER 18
|
||||
#define IRQ_ERROR 19
|
||||
|
|
32
ulib.c
32
ulib.c
|
@ -12,20 +12,20 @@ puts(char *s)
|
|||
char*
|
||||
strcpy(char *s, char *t)
|
||||
{
|
||||
char *os;
|
||||
|
||||
os = s;
|
||||
while((*s++ = *t++) != 0)
|
||||
;
|
||||
return os;
|
||||
char *os;
|
||||
|
||||
os = s;
|
||||
while((*s++ = *t++) != 0)
|
||||
;
|
||||
return os;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp(const char *p, const char *q)
|
||||
{
|
||||
while (*p && *p == *q)
|
||||
p++, q++;
|
||||
return (int) ((unsigned char) *p - (unsigned char) *q);
|
||||
while (*p && *p == *q)
|
||||
p++, q++;
|
||||
return (int) ((unsigned char) *p - (unsigned char) *q);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
|
@ -37,7 +37,7 @@ strlen(char *s)
|
|||
return n;
|
||||
}
|
||||
|
||||
void *
|
||||
void*
|
||||
memset(void *dst, int c, unsigned int n)
|
||||
{
|
||||
char *d = (char *) dst;
|
||||
|
@ -48,16 +48,16 @@ memset(void *dst, int c, unsigned int n)
|
|||
return dst;
|
||||
}
|
||||
|
||||
char *
|
||||
char*
|
||||
strchr(const char *s, char c)
|
||||
{
|
||||
for (; *s; s++)
|
||||
if (*s == c)
|
||||
return (char *) s;
|
||||
return 0;
|
||||
for (; *s; s++)
|
||||
if (*s == c)
|
||||
return (char *) s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
char*
|
||||
gets(char *buf, int max)
|
||||
{
|
||||
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) {
|
||||
if (p->s.size >= nunits) {
|
||||
if (p->s.size == nunits)
|
||||
prevp->s.ptr = p->s.ptr;
|
||||
prevp->s.ptr = p->s.ptr;
|
||||
else {
|
||||
p->s.size -= nunits;
|
||||
p += p->s.size;
|
||||
p->s.size = nunits;
|
||||
p->s.size -= nunits;
|
||||
p += p->s.size;
|
||||
p->s.size = nunits;
|
||||
}
|
||||
freep = prevp;
|
||||
return (void *) (p + 1);
|
||||
}
|
||||
if (p == freep)
|
||||
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);
|
||||
if (i == 0) {
|
||||
if (n == MAXFILE - 1) {
|
||||
printf(stdout, "read only %d blocks from big", n);
|
||||
exit();
|
||||
printf(stdout, "read only %d blocks from big", n);
|
||||
exit();
|
||||
}
|
||||
break;
|
||||
} else if (i != 512) {
|
||||
|
|
10
usys.S
10
usys.S
|
@ -2,11 +2,11 @@
|
|||
#include "traps.h"
|
||||
|
||||
#define STUB(name) \
|
||||
.globl name; \
|
||||
name: \
|
||||
movl $SYS_ ## name, %eax; \
|
||||
int $T_SYSCALL; \
|
||||
ret
|
||||
.globl name; \
|
||||
name: \
|
||||
movl $SYS_ ## name, %eax; \
|
||||
int $T_SYSCALL; \
|
||||
ret
|
||||
|
||||
STUB(fork)
|
||||
STUB(exit)
|
||||
|
|
|
@ -13,10 +13,10 @@ for(my $i = 0; $i < 256; $i++){
|
|||
print ".globl vector$i\n";
|
||||
print "vector$i:\n";
|
||||
if(($i < 8 || $i > 14) && $i != 17){
|
||||
print "\tpushl \$0\n";
|
||||
print " pushl \$0\n";
|
||||
}
|
||||
print "\tpushl \$$i\n";
|
||||
print "\tjmp alltraps\n";
|
||||
print " pushl \$$i\n";
|
||||
print " jmp alltraps\n";
|
||||
}
|
||||
|
||||
print "\n/* vector table */\n";
|
||||
|
@ -24,5 +24,5 @@ print ".data\n";
|
|||
print ".globl vectors\n";
|
||||
print "vectors:\n";
|
||||
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
|
||||
inb(int port)
|
||||
{
|
||||
uchar data;
|
||||
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
|
||||
return data;
|
||||
uchar data;
|
||||
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
|
||||
return data;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
insl(int port, void *addr, int cnt)
|
||||
{
|
||||
__asm __volatile("cld\n\trepne\n\tinsl" :
|
||||
"=D" (addr), "=c" (cnt) :
|
||||
"d" (port), "0" (addr), "1" (cnt) :
|
||||
"memory", "cc");
|
||||
__asm __volatile("cld\n\trepne\n\tinsl" :
|
||||
"=D" (addr), "=c" (cnt) :
|
||||
"d" (port), "0" (addr), "1" (cnt) :
|
||||
"memory", "cc");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
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
|
||||
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
|
||||
outsl(int port, const void *addr, int cnt)
|
||||
{
|
||||
__asm __volatile("cld\n\trepne\n\toutsl" :
|
||||
"=S" (addr), "=c" (cnt) :
|
||||
"d" (port), "0" (addr), "1" (cnt) :
|
||||
"cc");
|
||||
__asm __volatile("cld\n\trepne\n\toutsl" :
|
||||
"=S" (addr), "=c" (cnt) :
|
||||
"d" (port), "0" (addr), "1" (cnt) :
|
||||
"cc");
|
||||
}
|
||||
|
||||
struct segdesc;
|
||||
|
@ -41,13 +41,13 @@ struct segdesc;
|
|||
static __inline void
|
||||
lgdt(struct segdesc *p, int size)
|
||||
{
|
||||
volatile ushort pd[3];
|
||||
volatile ushort pd[3];
|
||||
|
||||
pd[0] = size-1;
|
||||
pd[1] = (uint)p;
|
||||
pd[2] = (uint)p >> 16;
|
||||
pd[0] = size-1;
|
||||
pd[1] = (uint)p;
|
||||
pd[2] = (uint)p >> 16;
|
||||
|
||||
asm volatile("lgdt (%0)" : : "g" (pd));
|
||||
asm volatile("lgdt (%0)" : : "g" (pd));
|
||||
}
|
||||
|
||||
struct gatedesc;
|
||||
|
@ -55,99 +55,99 @@ struct gatedesc;
|
|||
static __inline void
|
||||
lidt(struct gatedesc *p, int size)
|
||||
{
|
||||
volatile ushort pd[3];
|
||||
volatile ushort pd[3];
|
||||
|
||||
pd[0] = size-1;
|
||||
pd[1] = (uint)p;
|
||||
pd[2] = (uint)p >> 16;
|
||||
pd[0] = size-1;
|
||||
pd[1] = (uint)p;
|
||||
pd[2] = (uint)p >> 16;
|
||||
|
||||
asm volatile("lidt (%0)" : : "g" (pd));
|
||||
asm volatile("lidt (%0)" : : "g" (pd));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ltr(ushort sel)
|
||||
{
|
||||
__asm __volatile("ltr %0" : : "r" (sel));
|
||||
__asm __volatile("ltr %0" : : "r" (sel));
|
||||
}
|
||||
|
||||
static __inline uint
|
||||
read_eflags(void)
|
||||
{
|
||||
uint eflags;
|
||||
__asm __volatile("pushfl; popl %0" : "=r" (eflags));
|
||||
return eflags;
|
||||
uint eflags;
|
||||
__asm __volatile("pushfl; popl %0" : "=r" (eflags));
|
||||
return eflags;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
write_eflags(uint eflags)
|
||||
{
|
||||
__asm __volatile("pushl %0; popfl" : : "r" (eflags));
|
||||
__asm __volatile("pushl %0; popfl" : : "r" (eflags));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
cpuid(uint info, uint *eaxp, uint *ebxp, uint *ecxp, uint *edxp)
|
||||
{
|
||||
uint eax, ebx, ecx, edx;
|
||||
asm volatile("cpuid"
|
||||
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
|
||||
: "a" (info));
|
||||
if (eaxp)
|
||||
*eaxp = eax;
|
||||
if (ebxp)
|
||||
*ebxp = ebx;
|
||||
if (ecxp)
|
||||
*ecxp = ecx;
|
||||
if (edxp)
|
||||
*edxp = edx;
|
||||
uint eax, ebx, ecx, edx;
|
||||
asm volatile("cpuid" :
|
||||
"=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) :
|
||||
"a" (info));
|
||||
if (eaxp)
|
||||
*eaxp = eax;
|
||||
if (ebxp)
|
||||
*ebxp = ebx;
|
||||
if (ecxp)
|
||||
*ecxp = ecx;
|
||||
if (edxp)
|
||||
*edxp = edx;
|
||||
}
|
||||
|
||||
static __inline uint
|
||||
cmpxchg(uint oldval, uint newval, volatile uint* lock_addr)
|
||||
{
|
||||
uint result;
|
||||
__asm__ __volatile__(
|
||||
"lock; cmpxchgl %2, %0"
|
||||
:"+m" (*lock_addr), "=a" (result) : "r"(newval), "1"(oldval) : "cc"
|
||||
);
|
||||
__asm__ __volatile__("lock; cmpxchgl %2, %0" :
|
||||
"+m" (*lock_addr), "=a" (result) :
|
||||
"r"(newval), "1"(oldval) :
|
||||
"cc");
|
||||
return result;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
cli(void)
|
||||
{
|
||||
__asm__ volatile("cli");
|
||||
__asm__ volatile("cli");
|
||||
}
|
||||
|
||||
static __inline void
|
||||
sti(void)
|
||||
{
|
||||
__asm__ volatile("sti");
|
||||
__asm__ volatile("sti");
|
||||
}
|
||||
|
||||
struct trapframe {
|
||||
/* registers as pushed by pusha */
|
||||
uint edi;
|
||||
uint esi;
|
||||
uint ebp;
|
||||
uint oesp; /* Useless */
|
||||
uint ebx;
|
||||
uint edx;
|
||||
uint ecx;
|
||||
uint eax;
|
||||
/* rest of trap frame */
|
||||
ushort es;
|
||||
ushort padding1;
|
||||
ushort ds;
|
||||
ushort padding2;
|
||||
uint trapno;
|
||||
/* below here defined by x86 hardware */
|
||||
uint err;
|
||||
uint eip;
|
||||
ushort cs;
|
||||
ushort padding3;
|
||||
uint eflags;
|
||||
/* below here only when crossing rings, such as from user to kernel */
|
||||
uint esp;
|
||||
ushort ss;
|
||||
ushort padding4;
|
||||
/* registers as pushed by pusha */
|
||||
uint edi;
|
||||
uint esi;
|
||||
uint ebp;
|
||||
uint oesp; /* Useless */
|
||||
uint ebx;
|
||||
uint edx;
|
||||
uint ecx;
|
||||
uint eax;
|
||||
/* rest of trap frame */
|
||||
ushort es;
|
||||
ushort padding1;
|
||||
ushort ds;
|
||||
ushort padding2;
|
||||
uint trapno;
|
||||
/* below here defined by x86 hardware */
|
||||
uint err;
|
||||
uint eip;
|
||||
ushort cs;
|
||||
ushort padding3;
|
||||
uint eflags;
|
||||
/* below here only when crossing rings, such as from user to kernel */
|
||||
uint esp;
|
||||
ushort ss;
|
||||
ushort padding4;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue