├── LICENSE.txt ├── Makefile ├── README.md ├── README_uspi ├── contributors.md ├── include ├── arm.h ├── buf.h ├── defs.h ├── elf.h ├── fcntl.h ├── file.h ├── fs.h ├── fvp.h ├── mailbox.h ├── memlayout.h ├── mmu.h ├── param.h ├── proc.h ├── spinlock.h ├── stat.h ├── syscall.h ├── traps.h ├── types.h ├── user.h ├── uspi.h ├── uspi │ ├── assert.h │ ├── bcm2835.h │ ├── devicenameservice.h │ ├── dwhci.h │ ├── dwhcidevice.h │ ├── dwhciframeschednper.h │ ├── dwhciframeschednsplit.h │ ├── dwhciframeschedper.h │ ├── dwhciframescheduler.h │ ├── dwhciregister.h │ ├── dwhcirootport.h │ ├── dwhcixferstagedata.h │ ├── keymap.h │ ├── keymap_de.h │ ├── keymap_es.h │ ├── keymap_fr.h │ ├── keymap_it.h │ ├── keymap_uk.h │ ├── keymap_us.h │ ├── lan7800.h │ ├── macaddress.h │ ├── macros.h │ ├── smsc951x.h │ ├── stdarg.h │ ├── string.h │ ├── synchronize.h │ ├── types.h │ ├── usb.h │ ├── usbconfigparser.h │ ├── usbdevice.h │ ├── usbdevicefactory.h │ ├── usbendpoint.h │ ├── usbgamepad.h │ ├── usbhid.h │ ├── usbhostcontroller.h │ ├── usbhub.h │ ├── usbkeyboard.h │ ├── usbmassdevice.h │ ├── usbmidi.h │ ├── usbmouse.h │ ├── usbrequest.h │ ├── usbstandardhub.h │ ├── usbstring.h │ ├── uspilibrary.h │ └── util.h ├── uspienv │ ├── bcm2835.h │ ├── bcm2835int.h │ ├── memio.h │ └── timer.h └── uspios.h ├── kernel.ld ├── loader.S ├── loader.ld ├── source ├── LICENSE ├── bio.c ├── console.c ├── entry.S ├── exception.S ├── exec.c ├── file.c ├── font.bin ├── font1.bin ├── fs.c ├── fs.img ├── initcode ├── initcode.S ├── kalloc.c ├── log.c ├── mailbox.c ├── main.c ├── memide.c ├── mmu.c ├── pipe.c ├── proc.c ├── spinlock.c ├── string.c ├── syscall.c ├── sysfile.c ├── sysproc.c ├── timer.c ├── trap.c ├── uart.c ├── uart_pl011.c ├── usb.c ├── uspi_devicenameservice.c ├── uspi_dwhcidevice.c ├── uspi_dwhciframeschednper.c ├── uspi_dwhciframeschednsplit.c ├── uspi_dwhciframeschedper.c ├── uspi_dwhciregister.c ├── uspi_dwhcirootport.c ├── uspi_dwhcixferstagedata.c ├── uspi_keymap.c ├── uspi_lan7800.c ├── uspi_library.c ├── uspi_macaddress.c ├── uspi_smsc951x.c ├── uspi_string.c ├── uspi_synchronize.c ├── uspi_usbconfigparser.c ├── uspi_usbdevice.c ├── uspi_usbdevicefactory.c ├── uspi_usbendpoint.c ├── uspi_usbgamepad.c ├── uspi_usbkeyboard.c ├── uspi_usbmassdevice.c ├── uspi_usbmidi.c ├── uspi_usbmouse.c ├── uspi_usbrequest.c ├── uspi_usbstandardhub.c ├── uspi_usbstring.c ├── uspi_util.c ├── uspienv_delayloop.S ├── uspienv_memio.c ├── uspienv_timer.c └── vm.c ├── uprogs ├── LICENSE ├── Makefile ├── README ├── arm.h ├── benchmark.c ├── buf.h ├── cat.c ├── defs.h ├── echo.c ├── elf.h ├── fcntl.h ├── file.h ├── forktest.c ├── fs.h ├── grep.c ├── init.c ├── initcode.S ├── kill.c ├── ln.c ├── ls.c ├── memlayout.h ├── mkdir.c ├── mkfs.c ├── mmu.h ├── param.h ├── printf.c ├── proc.h ├── rm.c ├── sh.c ├── spinlock.h ├── stat.h ├── stressfs.c ├── syscall.h ├── timetest.c ├── traps.h ├── types.h ├── ulib.c ├── umalloc.c ├── user.h ├── usertests.c ├── usys.S ├── wc.c └── zombie.c └── xv6-guide.pdf /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019 The xv6 ARM contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /contributors.md: -------------------------------------------------------------------------------- 1 | # Acknowledgements: 2 | 3 | ## Porting xv6 to the Rasbperry Pi 4 | * Zhiyi Huang, University of Otago 5 | * Alex Bradbury, University of Cambridge 6 | * Alex Chadwick, University of Cambridge 7 | * Theo Markettos, University of Cambridge 8 | * Robert Mullins, University of Cambridge 9 | * Robert N. M. Watson, University of Cambridge 10 | 11 | ## Porting xv6 to the Raspberry Pi 2 12 | * Mahdi Amiri Kordestany, University of Otago 13 | 14 | ## Multiprocessing and caching 15 | * Harley Paterson, University of Otago 16 | -------------------------------------------------------------------------------- /include/arm.h: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * arm.h 3 | * by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | 10 | 11 | #define PSR_MODE_USR 0x00000010 12 | #define PSR_MODE_FIQ 0x00000011 13 | #define PSR_MODE_IRQ 0x00000012 14 | #define PSR_MODE_SVC 0x00000013 15 | #define PSR_MODE_MON 0x00000016 16 | #define PSR_MODE_ABT 0x00000017 17 | #define PSR_MODE_UND 0x0000001B 18 | #define PSR_MODE_SYS 0x0000001F 19 | #define PSR_MASK 0x0000001F 20 | #define USER_MODE 0x0 21 | 22 | #define PSR_DISABLE_IRQ 0x00000080 23 | #define PSR_DISABLE_FIQ 0x00000040 24 | 25 | #define PSR_V 0x10000000 26 | #define PSR_C 0x20000000 27 | #define PSR_Z 0x40000000 28 | #define PSR_N 0x80000000 29 | 30 | 31 | static inline uint 32 | inw(uint addr) 33 | { 34 | uint data; 35 | 36 | asm volatile("ldr %0,[%1]" : "=r"(data) : "r"(addr)); 37 | return data; 38 | } 39 | 40 | static inline void 41 | outw(uint addr, uint data) 42 | { 43 | asm volatile("str %1,[%0]" : : "r"(addr), "r"(data)); 44 | } 45 | 46 | 47 | // Layout of the trap frame built on the stack 48 | // by exception.s, and passed to trap(). 49 | struct trapframe { 50 | uint sp; // user mode sp 51 | uint r0; 52 | uint r1; 53 | uint r2; 54 | uint r3; 55 | uint r4; 56 | uint r5; 57 | uint r6; 58 | uint r7; 59 | uint r8; 60 | uint r9; 61 | uint r10; 62 | uint r11; 63 | uint r12; 64 | uint r13; 65 | uint r14; 66 | uint trapno; 67 | uint ifar; // Instruction Fault Address Register (IFAR) 68 | uint cpsr; 69 | uint spsr; // saved cpsr from the trapped/interrupted mode 70 | uint pc; // return address of the interrupted code 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /include/buf.h: -------------------------------------------------------------------------------- 1 | struct buf { 2 | int flags; 3 | uint dev; 4 | uint sector; 5 | struct buf *prev; // LRU cache list 6 | struct buf *next; 7 | struct buf *qnext; // disk queue 8 | uchar data[512]; 9 | }; 10 | #define B_BUSY 0x1 // buffer is locked by some process 11 | #define B_VALID 0x2 // buffer has been read from disk 12 | #define B_DIRTY 0x4 // buffer needs to be written to disk 13 | 14 | -------------------------------------------------------------------------------- /include/elf.h: -------------------------------------------------------------------------------- 1 | // Format of an ELF executable file 2 | 3 | #define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian 4 | 5 | // File header 6 | struct elfhdr { 7 | uint magic; // must equal ELF_MAGIC 8 | uchar elf[12]; 9 | ushort type; 10 | ushort machine; 11 | uint version; 12 | uint entry; 13 | uint phoff; 14 | uint shoff; 15 | uint flags; 16 | ushort ehsize; 17 | ushort phentsize; 18 | ushort phnum; 19 | ushort shentsize; 20 | ushort shnum; 21 | ushort shstrndx; 22 | }; 23 | 24 | // Program section header 25 | struct proghdr { 26 | uint type; 27 | uint off; 28 | uint vaddr; 29 | uint paddr; 30 | uint filesz; 31 | uint memsz; 32 | uint flags; 33 | uint align; 34 | }; 35 | 36 | // Values for Proghdr type 37 | #define ELF_PROG_LOAD 1 38 | 39 | // Flag bits for Proghdr flags 40 | #define ELF_PROG_FLAG_EXEC 1 41 | #define ELF_PROG_FLAG_WRITE 2 42 | #define ELF_PROG_FLAG_READ 4 43 | -------------------------------------------------------------------------------- /include/fcntl.h: -------------------------------------------------------------------------------- 1 | #define O_RDONLY 0x000 2 | #define O_WRONLY 0x001 3 | #define O_RDWR 0x002 4 | #define O_CREATE 0x200 5 | -------------------------------------------------------------------------------- /include/file.h: -------------------------------------------------------------------------------- 1 | struct file { 2 | enum { FD_NONE, FD_PIPE, FD_INODE } type; 3 | int ref; // reference count 4 | char readable; 5 | char writable; 6 | struct pipe *pipe; 7 | struct inode *ip; 8 | uint off; 9 | }; 10 | 11 | 12 | // in-memory copy of an inode 13 | struct inode { 14 | uint dev; // Device number 15 | uint inum; // Inode number 16 | int ref; // Reference count 17 | int flags; // I_BUSY, I_VALID 18 | 19 | short type; // copy of disk inode 20 | short major; 21 | short minor; 22 | short nlink; 23 | uint size; 24 | uint addrs[NDIRECT+1]; 25 | }; 26 | #define I_BUSY 0x1 27 | #define I_VALID 0x2 28 | 29 | // table mapping major device number to 30 | // device functions 31 | struct devsw { 32 | int (*read)(struct inode*, char*, int); 33 | int (*write)(struct inode*, char*, int); 34 | }; 35 | 36 | extern struct devsw devsw[]; 37 | 38 | #define CONSOLE 1 39 | -------------------------------------------------------------------------------- /include/fs.h: -------------------------------------------------------------------------------- 1 | // On-disk file system format. 2 | // Both the kernel and user programs use this header file. 3 | 4 | // Block 0 is unused. 5 | // Block 1 is super block. 6 | // Blocks 2 through sb.ninodes/IPB hold inodes. 7 | // Then free bitmap blocks holding sb.size bits. 8 | // Then sb.nblocks data blocks. 9 | // Then sb.nlog log blocks. 10 | 11 | #define ROOTINO 1 // root i-number 12 | #define BSIZE 512 // block size 13 | 14 | // File system super block 15 | struct superblock { 16 | uint size; // Size of file system image (blocks) 17 | uint nblocks; // Number of data blocks 18 | uint ninodes; // Number of inodes. 19 | uint nlog; // Number of log blocks 20 | }; 21 | 22 | #define NDIRECT 12 23 | #define NINDIRECT (BSIZE / sizeof(uint)) 24 | #define MAXFILE (NDIRECT + NINDIRECT) 25 | 26 | // On-disk inode structure 27 | struct dinode { 28 | short type; // File type 29 | short major; // Major device number (T_DEV only) 30 | short minor; // Minor device number (T_DEV only) 31 | short nlink; // Number of links to inode in file system 32 | uint size; // Size of file (bytes) 33 | uint addrs[NDIRECT+1]; // Data block addresses 34 | }; 35 | 36 | // Inodes per block. 37 | #define IPB (BSIZE / sizeof(struct dinode)) 38 | 39 | // Block containing inode i 40 | #define IBLOCK(i) ((i) / IPB + 2) 41 | 42 | // Bitmap bits per block 43 | #define BPB (BSIZE*8) 44 | 45 | // Block containing bit for block b 46 | #define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3) 47 | 48 | // Directory is a file containing a sequence of dirent structures. 49 | #define DIRSIZ 14 50 | 51 | struct dirent { 52 | ushort inum; 53 | char name[DIRSIZ]; 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /include/fvp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fvp.h 3 | * 4 | * Created on: Dec 2, 2016 5 | * Author: Mahdi Amiri 6 | */ 7 | 8 | #ifndef FVP_H 9 | #define FVP_H 10 | #define FVP_PL011_BASE (MMIO_VA + 0x90000) 11 | #define FVP_PL011_UARTDR FVP_PL011_BASE // Data register 12 | #define FVP_PL011_UARTFR (FVP_PL011_BASE+0x18) // Flag register 13 | #define FVP_PL011_UARTFR_TXFF (1 << 5) // Transmit FIFO full @ UARTFR 14 | #define FVP_PL011_UARTFR_RXFE (1 << 4) // Receive FIFO empty @ UARTFR 15 | #define FVP_PL011_UARTCR (FVP_PL011_BASE+0x30) // Control register 16 | #define FVP_PL011_UARTCR_UARTEN 1 // UART enable @ UARTCR 17 | #define FVP_PL011_UARTCR_TXE (1<<8) // Transmit enable @ UARTCR 18 | #define FVP_PL011_UARTCR_RXE (1<<9) // Receive enable @ UARTCR 19 | #define FVP_PL011_UARTIMSC (FVP_PL011_BASE+0x38) // Interrupt mask set/clear register 20 | #define FVP_PL011_UARTIMSC_RXIM (1<<4) // Receive interrupt mask. 21 | 22 | //#define FVP_GLOBAL_TIMER_BASE ((uint) &__va_private_start + 0x0200 ) 23 | #define FVP_GLOBAL_TIMER_BASE (MMIO_VA + 0x110000) 24 | #define FVP_TIMER1_LOAD FVP_GLOBAL_TIMER_BASE 25 | #define FVP_TIMER1_VALUE ( FVP_GLOBAL_TIMER_BASE + 0x4 ) 26 | #define FVP_TIMER1_CNTL ( FVP_GLOBAL_TIMER_BASE + 0x8 ) 27 | #define FVP_TIMER1_INT_CTRL ( FVP_GLOBAL_TIMER_BASE + 0xC ) 28 | #define FVP_TIMER1_RIS ( FVP_GLOBAL_TIMER_BASE + 0x10 ) 29 | #define FVP_TIMER1_MIS ( FVP_GLOBAL_TIMER_BASE + 0x14 ) 30 | #define FVP_TIMER1_BGL ( FVP_GLOBAL_TIMER_BASE + 0x18 ) 31 | 32 | #define ARM_GLOBAL_TIMER_BASE ((uint) &__va_private_start + 0x0200 ) 33 | #define ARM_GLOBAL_TIMER_VALUE_LO ARM_GLOBAL_TIMER_BASE // Load Register 34 | #define ARM_GLOBAL_TIMER_VALUE_HI ( ARM_GLOBAL_TIMER_BASE + 0x4 ) // Value 35 | #define ARM_GLOBAL_TIMER_CNTL ( ARM_GLOBAL_TIMER_BASE + 0x8 ) // Value 36 | #define ARM_GLOBAL_TIMER_INT_STATUS ( ARM_GLOBAL_TIMER_BASE + 0xC ) // Value 37 | #define ARM_GLOBAL_TIMER_CMP_LO ( ARM_GLOBAL_TIMER_BASE + 0x10 ) // Value 38 | #define ARM_GLOBAL_TIMER_CMP_HI ( ARM_GLOBAL_TIMER_BASE + 0x14 ) // Value 39 | #define ARM_GLOBAL_TIMER_AUTO_INC ( ARM_GLOBAL_TIMER_BASE + 0x18 ) // Value 40 | 41 | #endif /* FVP_H */ 42 | -------------------------------------------------------------------------------- /include/mailbox.h: -------------------------------------------------------------------------------- 1 | #define MAILBOX_BASE (MMIO_VA+0x00B880) 2 | 3 | #define MPI_REQUEST 0x00000000 4 | #define MPI_RESPONSE_OK 0x80000000 5 | #define MPI_RESPONSE_ERR 0x80000001 6 | 7 | #define POS_OVERALL_LENGTH 0 8 | #define POS_RV 1 9 | #define POS_TAG 2 10 | 11 | #define POS_TAG_ID 0 12 | #define POS_TAG_BUFLEN 1 13 | #define POS_TAG_DATALEN 2 14 | #define POS_TAG_DATA 3 15 | 16 | 17 | #define MB_HEADER_LENGTH 2 18 | #define TAG_HEADER_LENGTH 3 19 | 20 | /* to be extended */ 21 | #define MPI_TAG_GET_FIRMWARE 0x00000001 22 | #define MPI_TAG_GET_BOARD_MODEL 0x00010001 23 | #define MPI_TAG_GET_BOARD_REVISION 0x00010002 24 | #define MPI_TAG_GET_MAC_ADDRESS 0x00010003 25 | #define MPI_TAG_GET_BOARD_SERIAL 0x00010004 26 | #define MPI_TAG_GET_ARM_MEMORY 0x00010005 27 | #define MPI_TAG_GET_VC_MEMORY 0x00010006 28 | #define MPI_TAG_GET_CLOCKS 0x00010007 29 | #define MPI_TAG_GET_COMMANDLINE 0x00050001 30 | #define MPI_TAG_GET_DMA_CHANNELS 0x00060001 31 | #define MPI_TAG_GET_POWER_STATE 0x00020001 32 | #define MPI_TAG_SET_POWER_STATE 0x00028001 33 | #define MPI_TAG_GET_TIMING 0x00020002 34 | #define MPI_TAG_GET_FIRMWARE 0x00000001 35 | #define MPI_TAG_GET_CLOCK_STATE 0x00030001 36 | #define MPI_TAG_SET_CLOCK_STATE 0x00038001 37 | 38 | 39 | -------------------------------------------------------------------------------- /include/memlayout.h: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * memlayout.h 3 | * by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | 10 | // Memory layout 11 | 12 | #define PHYSTOP (PHYSTART+PHYSIZE) 13 | 14 | #define USERBOUND 0x40000000 // maximum user space due to one page pgd 15 | #define GPUMEMBASE 0x40000000 16 | #define GPUMEMSIZE (1024*MBYTE) 17 | 18 | #define TVSIZE 0x1000 19 | 20 | static inline uint v2p(void *a) { return ((uint) (a)) - (KERNBASE-PHYSTART); } 21 | static inline void *p2v(uint a) { return (void *) ((a) + (KERNBASE-PHYSTART)); } 22 | 23 | #define V2P(a) (((uint) (a)) - (KERNBASE-PHYSTART)) 24 | #define P2V(a) (((void *) (a)) + (KERNBASE-PHYSTART)) 25 | 26 | #define V2P_WO(x) ((x) - (KERNBASE-PHYSTART)) // same as V2P, but without casts 27 | #define P2V_WO(x) ((x) + (KERNBASE-PHYSTART)) // same as V2P, but without casts 28 | 29 | -------------------------------------------------------------------------------- /include/param.h: -------------------------------------------------------------------------------- 1 | #define NPROC 64 // maximum number of processes 2 | #define KSTACKSIZE 4096 // size of per-process kernel stack 3 | #define NCPU 4 // maximum number of CPUs 4 | #define NOFILE 16 // open files per process 5 | #define NFILE 100 // open files per system 6 | #define NBUF 10 // size of disk block cache 7 | #define NINODE 50 // maximum number of active i-nodes 8 | #define NDEV 10 // maximum major device number 9 | #define ROOTDEV 1 // device number of file system root disk 10 | #define MAXARG 32 // max exec arguments 11 | #define LOGSIZE 10 // max data sectors in on-disk log 12 | 13 | -------------------------------------------------------------------------------- /include/proc.h: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * proc.h 3 | * adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | 10 | // Segments in proc->gdt. 11 | #define NSEGS 7 12 | 13 | // Per-CPU state 14 | struct cpu { 15 | uchar id; // Local APIC ID; index into cpus[] below 16 | struct context *scheduler; // swtch() here to enter scheduler 17 | int first_sched; // Has the CPU entered the scheduler before. 18 | volatile uint started; // Has the CPU started? 19 | int ncli; // Depth of pushcli nesting. 20 | int intena; // Were interrupts enabled before pushcli? 21 | pde_t *kpgdir; // The page table for the CPU. 22 | 23 | // Cpu-local storage variables; see below 24 | struct cpu *cpu; 25 | struct proc *proc; // The currently-running process. 26 | }; 27 | 28 | struct cpu cpus[NCPU]; 29 | //extern int ncpu; 30 | 31 | // Per-CPU variables, holding pointers to the 32 | // current cpu and to the current process. 33 | // The asm suffix tells gcc to use "%gs:0" to refer to cpu 34 | // and "%gs:4" to refer to proc. seginit sets up the 35 | // %gs segment register so that %gs refers to the memory 36 | // holding those two variables in the local cpu's struct cpu. 37 | // This is similar to how thread-local variables are implemented 38 | // in thread libraries such as Linux pthreads. 39 | //extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] 40 | //extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc 41 | 42 | #define curr_cpu (&cpus[cpu_id()]) 43 | #define curr_proc (cpus[cpu_id()].proc) 44 | 45 | //PAGEBREAK: 17 46 | // Saved registers for kernel context switches. 47 | // Don't need to save all the segment registers (%cs, etc), 48 | // because they are constant across kernel contexts. 49 | // Don't need to save %eax, %ecx, %edx, because the 50 | // x86 convention is that the caller has saved them. 51 | // Contexts are stored at the bottom of the stack they 52 | // describe; the stack pointer is the address of the context. 53 | // The layout of the context matches the layout of the stack in swtch.S 54 | // at the "Switch stacks" comment. Switch doesn't save eip explicitly, 55 | // but it is on the stack and allocproc() manipulates it. 56 | struct context { 57 | uint r4; 58 | uint r5; 59 | uint r6; 60 | uint r7; 61 | uint r8; 62 | uint r9; 63 | uint r10; 64 | uint r11; 65 | uint r12; 66 | uint lr; 67 | uint pc; 68 | }; 69 | 70 | enum procstate { UNUSED=0, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; 71 | 72 | enum cpustate { UNSTARTED=1, STARTED=1,CENTRY=2, SCHED=3, ERROR=0xff }; 73 | 74 | // Per-process state 75 | struct proc { 76 | uint sz; // Size of process memory (bytes) 77 | pde_t* pgdir; // Page table 78 | char *kstack; // Bottom of kernel stack for this process 79 | enum procstate state; // Process state 80 | volatile int pid; // Process ID 81 | struct proc *parent; // Parent process 82 | struct trapframe *tf; // Trap frame for current syscall 83 | struct context *context; // swtch() here to run process 84 | void *chan; // If non-zero, sleeping on chan 85 | int killed; // If non-zero, have been killed 86 | struct file *ofile[NOFILE]; // Open files 87 | struct inode *cwd; // Current directory 88 | char name[16]; // Process name (debugging) 89 | }; 90 | 91 | // Process memory is laid out contiguously, low addresses first: 92 | // text 93 | // original data and bss 94 | // fixed-size stack 95 | // expandable heap 96 | -------------------------------------------------------------------------------- /include/spinlock.h: -------------------------------------------------------------------------------- 1 | // Mutual exclusion lock. 2 | struct spinlock { 3 | u32 locked __attribute((aligned (4))); // Is the lock held? 4 | 5 | // For debugging: 6 | char *name; // Name of lock. 7 | struct cpu *cpu; // The cpu holding the lock. 8 | uint pcs[10]; // The call stack (an array of program counters) 9 | // that locked the lock. 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /include/stat.h: -------------------------------------------------------------------------------- 1 | #define T_DIR 1 // Directory 2 | #define T_FILE 2 // File 3 | #define T_DEV 3 // Device 4 | 5 | struct stat { 6 | short type; // Type of file 7 | int dev; // File system's disk device 8 | uint ino; // Inode number 9 | short nlink; // Number of links to file 10 | uint size; // Size of file in bytes 11 | }; 12 | -------------------------------------------------------------------------------- /include/syscall.h: -------------------------------------------------------------------------------- 1 | // System call numbers 2 | #define SYS_fork 1 3 | #define SYS_exit 2 4 | #define SYS_wait 3 5 | #define SYS_pipe 4 6 | #define SYS_read 5 7 | #define SYS_kill 6 8 | #define SYS_exec 7 9 | #define SYS_fstat 8 10 | #define SYS_chdir 9 11 | #define SYS_dup 10 12 | #define SYS_getpid 11 13 | #define SYS_sbrk 12 14 | #define SYS_sleep 13 15 | #define SYS_uptime 14 16 | #define SYS_open 15 17 | #define SYS_write 16 18 | #define SYS_mknod 17 19 | #define SYS_unlink 18 20 | #define SYS_link 19 21 | #define SYS_mkdir 20 22 | #define SYS_close 21 23 | #define SYS_time 22 24 | -------------------------------------------------------------------------------- /include/traps.h: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * traps.h 3 | * by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | 10 | // These are arbitrarily chosen, but with care not to overlap 11 | // processor defined exceptions or interrupt vectors. 12 | #define T_SYSCALL 0x40 // system call 13 | #define T_IRQ 0x80 // interrupt 14 | #define T_UND 0x01 // undefined instruction 15 | #define T_PABT 0x02 // prefetch abort 16 | #define T_DABT 0x04 // data abort 17 | 18 | #define IRQ_TIMER3 3 19 | #define IRQ_MINIUART 29 20 | 21 | #define INT_REGS_BASE (MMIO_VA+0xB200) 22 | -------------------------------------------------------------------------------- /include/types.h: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * types.h 3 | * by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | typedef unsigned int u32; 10 | typedef unsigned short u16; 11 | typedef unsigned char u8; 12 | typedef unsigned long long u64; 13 | 14 | typedef unsigned int uint; 15 | typedef unsigned short ushort; 16 | typedef unsigned char uchar; 17 | typedef uint pde_t; 18 | typedef uint pte_t; 19 | 20 | 21 | /* trap vectors layout at virtual 22 | address HVECTORS (and KZERO(0x80000000), doubled mapped).*/ 23 | typedef struct Vpage0 { 24 | void (*vectors[8])(void); 25 | uint vtable[8]; 26 | } Vpage0; 27 | 28 | 29 | /* ARM interrupt control registers */ 30 | typedef struct intctrlregs { 31 | uint armpending; 32 | uint gpupending[2]; 33 | uint fiqctrl; 34 | uint gpuenable[2]; 35 | uint armenable; 36 | uint gpudisable[2]; 37 | uint armdisable; 38 | } intctrlregs; 39 | 40 | struct framebufdescription { 41 | uint width; //width 42 | uint height; // height 43 | uint v_width; // virtual width 44 | uint v_height; // virtual height 45 | uint pitch; // GPU pitch 46 | uint depth; // bit depth 47 | uint x; 48 | uint y; 49 | uint fbp; //GPU framebuffer pointer 50 | uint fbs; // GPU framebuffer size 51 | }; 52 | 53 | typedef struct framebufdescription FBI; 54 | -------------------------------------------------------------------------------- /include/user.h: -------------------------------------------------------------------------------- 1 | struct stat; 2 | 3 | // system calls 4 | int fork(void); 5 | int exit(void) __attribute__((noreturn)); 6 | int wait(void); 7 | int pipe(int*); 8 | int write(int, void*, int); 9 | int read(int, void*, int); 10 | int close(int); 11 | int kill(int); 12 | int exec(char*, char**); 13 | int open(char*, int); 14 | int mknod(char*, short, short); 15 | int unlink(char*); 16 | int fstat(int fd, struct stat*); 17 | int link(char*, char*); 18 | int mkdir(char*); 19 | int chdir(char*); 20 | int dup(int); 21 | int getpid(void); 22 | char* sbrk(int); 23 | int sleep(int); 24 | int uptime(void); 25 | 26 | // ulib.c 27 | int stat(char*, struct stat*); 28 | char* strcpy(char*, char*); 29 | void *memmove(void*, void*, int); 30 | char* strchr(const char*, char c); 31 | int strcmp(const char*, const char*); 32 | void printf(int, char*, ...); 33 | char* gets(char*, int max); 34 | uint strlen(char*); 35 | void* memset(void*, int, uint); 36 | void* malloc(uint); 37 | void free(void*); 38 | int atoi(const char*); 39 | -------------------------------------------------------------------------------- /include/uspi/assert.h: -------------------------------------------------------------------------------- 1 | // 2 | // assert.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_assert_h 21 | #define _uspi_assert_h 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | #ifdef NDEBUG 28 | #define assert(expr) ((void) 0) 29 | #else 30 | void uspi_assertion_failed (const char *pExpr, const char *pFile, unsigned nLine); 31 | 32 | #define assert(expr) ((expr) ? ((void) 0) : uspi_assertion_failed (#expr, __FILE__, __LINE__)) 33 | #endif 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/uspi/bcm2835.h: -------------------------------------------------------------------------------- 1 | // 2 | // bcm2835.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014-2017 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_bcm2835_h 21 | #define _uspi_bcm2835_h 22 | 23 | #include 24 | 25 | #if RASPPI == 1 26 | #define ARM_IO_BASE 0x20000000 27 | #else 28 | #define ARM_IO_BASE MMIO_VA // 0x3F000000 29 | #endif 30 | 31 | #define GPU_IO_BASE 0x7E000000 32 | 33 | #define GPU_CACHED_BASE 0x40000000 34 | #define GPU_UNCACHED_BASE 0xC0000000 35 | 36 | #if RASPPI == 1 37 | #ifdef GPU_L2_CACHE_ENABLED 38 | #define GPU_MEM_BASE GPU_CACHED_BASE 39 | #else 40 | #define GPU_MEM_BASE GPU_UNCACHED_BASE 41 | #endif 42 | #else 43 | #define GPU_MEM_BASE GPU_UNCACHED_BASE 44 | #endif 45 | 46 | // Convert physical ARM address into bus address 47 | // (does even work, if a bus address is provided already) 48 | #define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | GPU_MEM_BASE) 49 | 50 | // 51 | // USB Host Controller 52 | // 53 | #define ARM_USB_BASE (ARM_IO_BASE + 0x980000) 54 | 55 | #define ARM_USB_CORE_BASE ARM_USB_BASE 56 | #define ARM_USB_HOST_BASE (ARM_USB_BASE + 0x400) 57 | #define ARM_USB_POWER (ARM_USB_BASE + 0xE00) 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/uspi/devicenameservice.h: -------------------------------------------------------------------------------- 1 | // 2 | // devicenameservice.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_devicenameservice_h 21 | #define _uspi_devicenameservice_h 22 | 23 | #include 24 | 25 | typedef struct TDeviceInfo 26 | { 27 | struct TDeviceInfo *pNext; 28 | char *pName; 29 | void *pDevice; 30 | boolean bBlockDevice; 31 | } 32 | TDeviceInfo; 33 | 34 | typedef struct TDeviceNameService 35 | { 36 | TDeviceInfo *m_pList; 37 | } 38 | TDeviceNameService; 39 | 40 | void DeviceNameService (TDeviceNameService *pThis); 41 | void _DeviceNameService (TDeviceNameService *pThis); 42 | 43 | void DeviceNameServiceAddDevice (TDeviceNameService *pThis, const char *pName, void *pDevice, boolean bBlockDevice); 44 | 45 | void *DeviceNameServiceGetDevice (TDeviceNameService *pThis, const char *pName, boolean bBlockDevice); 46 | 47 | TDeviceNameService *DeviceNameServiceGet (void); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/uspi/dwhcidevice.h: -------------------------------------------------------------------------------- 1 | // 2 | // dwhcidevice.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _dwhcidevice_h 21 | #define _dwhcidevice_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | typedef struct TDWHCIDevice 39 | { 40 | unsigned m_nChannels; 41 | volatile unsigned m_nChannelAllocated; // one bit per channel, set if allocated 42 | 43 | TDWHCITransferStageData *m_pStageData[DWHCI_MAX_CHANNELS]; 44 | 45 | volatile boolean m_bWaiting; 46 | 47 | TDWHCIRootPort m_RootPort; 48 | } 49 | TDWHCIDevice; 50 | 51 | void DWHCIDevice (TDWHCIDevice *pThis); 52 | void _DWHCIDevice (TDWHCIDevice *pThis); 53 | 54 | boolean DWHCIDeviceInitialize (TDWHCIDevice *pThis); 55 | 56 | // returns resulting length or < 0 on failure 57 | int DWHCIDeviceGetDescriptor (TDWHCIDevice *pThis, TUSBEndpoint *pEndpoint, 58 | unsigned char ucType, unsigned char ucIndex, 59 | void *pBuffer, unsigned nBufSize, 60 | unsigned char ucRequestType /* = REQUEST_IN */); 61 | 62 | boolean DWHCIDeviceSetAddress (TDWHCIDevice *pThis, TUSBEndpoint *pEndpoint, u8 ucDeviceAddress); 63 | 64 | boolean DWHCIDeviceSetConfiguration (TDWHCIDevice *pThis, TUSBEndpoint *pEndpoint, u8 ucConfigurationValue); 65 | 66 | // returns resulting length or < 0 on failure 67 | int DWHCIDeviceControlMessage (TDWHCIDevice *pThis, TUSBEndpoint *pEndpoint, 68 | u8 ucRequestType, u8 ucRequest, u16 usValue, u16 usIndex, 69 | void *pData, u16 usDataSize); 70 | 71 | // returns resulting length or < 0 on failure 72 | int DWHCIDeviceTransfer (TDWHCIDevice *pThis, TUSBEndpoint *pEndpoint, void *pBuffer, unsigned nBufSize); 73 | 74 | boolean DWHCIDeviceSubmitBlockingRequest (TDWHCIDevice *pThis, TUSBRequest *pURB); 75 | boolean DWHCIDeviceSubmitAsyncRequest (TDWHCIDevice *pThis, TUSBRequest *pURB); 76 | 77 | TUSBSpeed DWHCIDeviceGetPortSpeed (TDWHCIDevice *pThis); 78 | boolean DWHCIDeviceOvercurrentDetected (TDWHCIDevice *pThis); 79 | void DWHCIDeviceDisableRootPort (TDWHCIDevice *pThis); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/uspi/dwhciframeschednper.h: -------------------------------------------------------------------------------- 1 | // 2 | // dwhciframeschednper.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_dwhciframeschednper_h 21 | #define _uspi_dwhciframeschednper_h 22 | 23 | #include 24 | #include 25 | 26 | typedef struct TDWHCIFrameSchedulerNonPeriodic 27 | { 28 | TDWHCIFrameScheduler m_DWHCIFrameScheduler; 29 | 30 | unsigned m_nState; 31 | unsigned m_nTries; 32 | } 33 | TDWHCIFrameSchedulerNonPeriodic; 34 | 35 | void DWHCIFrameSchedulerNonPeriodic (TDWHCIFrameSchedulerNonPeriodic *pThis); 36 | void _DWHCIFrameSchedulerNonPeriodic (TDWHCIFrameScheduler *pBase); 37 | 38 | void DWHCIFrameSchedulerNonPeriodicStartSplit (TDWHCIFrameScheduler *pBase); 39 | boolean DWHCIFrameSchedulerNonPeriodicCompleteSplit (TDWHCIFrameScheduler *pBase); 40 | void DWHCIFrameSchedulerNonPeriodicTransactionComplete (TDWHCIFrameScheduler *pBase, u32 nStatus); 41 | 42 | void DWHCIFrameSchedulerNonPeriodicWaitForFrame (TDWHCIFrameScheduler *pBase); 43 | 44 | boolean DWHCIFrameSchedulerNonPeriodicIsOddFrame (TDWHCIFrameScheduler *pBase); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/uspi/dwhciframeschednsplit.h: -------------------------------------------------------------------------------- 1 | // 2 | // dwhciframeschednsplit.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_dwhciframeschednsplit_h 21 | #define _uspi_dwhciframeschednsplit_h 22 | 23 | #include 24 | #include 25 | 26 | typedef struct TDWHCIFrameSchedulerNoSplit 27 | { 28 | TDWHCIFrameScheduler m_DWHCIFrameScheduler; 29 | 30 | boolean m_bIsPeriodic; 31 | unsigned m_nNextFrame; 32 | } 33 | TDWHCIFrameSchedulerNoSplit; 34 | 35 | void DWHCIFrameSchedulerNoSplit (TDWHCIFrameSchedulerNoSplit *pThis, boolean bIsPeriodic); 36 | void _DWHCIFrameSchedulerNoSplit (TDWHCIFrameScheduler *pBase); 37 | 38 | void DWHCIFrameSchedulerNoSplitStartSplit (TDWHCIFrameScheduler *pBase); 39 | boolean DWHCIFrameSchedulerNoSplitCompleteSplit (TDWHCIFrameScheduler *pBase); 40 | void DWHCIFrameSchedulerNoSplitTransactionComplete (TDWHCIFrameScheduler *pBase, u32 nStatus); 41 | 42 | void DWHCIFrameSchedulerNoSplitWaitForFrame (TDWHCIFrameScheduler *pBase); 43 | 44 | boolean DWHCIFrameSchedulerNoSplitIsOddFrame (TDWHCIFrameScheduler *pBase); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/uspi/dwhciframeschedper.h: -------------------------------------------------------------------------------- 1 | // 2 | // dwhciframeschedper.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_dwhciframeschedper_h 21 | #define _uspi_dwhciframeschedper_h 22 | 23 | #include 24 | #include 25 | 26 | typedef struct TDWHCIFrameSchedulerPeriodic 27 | { 28 | TDWHCIFrameScheduler m_DWHCIFrameScheduler; 29 | 30 | unsigned m_nState; 31 | unsigned m_nTries; 32 | 33 | unsigned m_nNextFrame; 34 | } 35 | TDWHCIFrameSchedulerPeriodic; 36 | 37 | void DWHCIFrameSchedulerPeriodic (TDWHCIFrameSchedulerPeriodic *pThis); 38 | void _DWHCIFrameSchedulerPeriodic (TDWHCIFrameScheduler *pBase); 39 | 40 | void DWHCIFrameSchedulerPeriodicStartSplit (TDWHCIFrameScheduler *pBase); 41 | boolean DWHCIFrameSchedulerPeriodicCompleteSplit (TDWHCIFrameScheduler *pBase); 42 | void DWHCIFrameSchedulerPeriodicTransactionComplete (TDWHCIFrameScheduler *pBase, u32 nStatus); 43 | 44 | void DWHCIFrameSchedulerPeriodicWaitForFrame (TDWHCIFrameScheduler *pBase); 45 | 46 | boolean DWHCIFrameSchedulerPeriodicIsOddFrame (TDWHCIFrameScheduler *pBase); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/uspi/dwhciframescheduler.h: -------------------------------------------------------------------------------- 1 | // 2 | // dwhciframescheduler.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_dwhciframescheduler_h 21 | #define _uspi_dwhciframescheduler_h 22 | 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | typedef struct TDWHCIFrameScheduler 30 | { 31 | void (*_DWHCIFrameScheduler) (struct TDWHCIFrameScheduler *pThis); 32 | 33 | void (*StartSplit) (struct TDWHCIFrameScheduler *pThis); 34 | boolean (*CompleteSplit) (struct TDWHCIFrameScheduler *pThis); 35 | void (*TransactionComplete) (struct TDWHCIFrameScheduler *pThis, u32 nStatus); 36 | 37 | void (*WaitForFrame) (struct TDWHCIFrameScheduler *pThis); 38 | 39 | boolean (*IsOddFrame) (struct TDWHCIFrameScheduler *pThis); 40 | } 41 | TDWHCIFrameScheduler; 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/uspi/dwhciregister.h: -------------------------------------------------------------------------------- 1 | // 2 | // dwhciregister.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_dwhciregister_h 21 | #define _uspi_dwhciregister_h 22 | 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef struct TDWHCIRegister 31 | { 32 | boolean m_bValid; 33 | u32 m_nAddress; 34 | u32 m_nBuffer; 35 | } 36 | TDWHCIRegister; 37 | 38 | void DWHCIRegister (TDWHCIRegister *pThis, u32 nAddress); 39 | void DWHCIRegister2 (TDWHCIRegister *pThis, u32 nAddress, u32 nValue); 40 | void _DWHCIRegister (TDWHCIRegister *pThis); 41 | 42 | u32 DWHCIRegisterRead (TDWHCIRegister *pThis); 43 | void DWHCIRegisterWrite (TDWHCIRegister *pThis); 44 | 45 | u32 DWHCIRegisterGet (TDWHCIRegister *pThis); 46 | void DWHCIRegisterSet (TDWHCIRegister *pThis, u32 nValue); 47 | 48 | boolean DWHCIRegisterIsSet (TDWHCIRegister *pThis, u32 nMask); 49 | 50 | void DWHCIRegisterAnd (TDWHCIRegister *pThis, u32 nMask); 51 | void DWHCIRegisterOr (TDWHCIRegister *pThis, u32 nMask); 52 | 53 | void DWHCIRegisterClearBit (TDWHCIRegister *pThis, unsigned nBit); 54 | void DWHCIRegisterSetBit (TDWHCIRegister *pThis, unsigned nBit); 55 | void DWHCIRegisterClearAll (TDWHCIRegister *pThis); 56 | void DWHCIRegisterSetAll (TDWHCIRegister *pThis); 57 | 58 | #ifndef NDEBUG 59 | 60 | void DWHCIRegisterDump (TDWHCIRegister *pThis); 61 | 62 | #endif 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /include/uspi/dwhcirootport.h: -------------------------------------------------------------------------------- 1 | // 2 | // dwhcirootport.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_dwhcirootport_h 21 | #define _uspi_dwhcirootport_h 22 | 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | struct TDWHCIDevice; 31 | 32 | typedef struct TDWHCIRootPort 33 | { 34 | struct TDWHCIDevice *m_pHost; 35 | 36 | TUSBDevice *m_pDevice; 37 | } 38 | TDWHCIRootPort; 39 | 40 | void DWHCIRootPort (TDWHCIRootPort *pThis, struct TDWHCIDevice *pHost); 41 | void _DWHCIRootPort (TDWHCIRootPort *pThis); 42 | 43 | boolean DWHCIRootPortInitialize (TDWHCIRootPort *pThis); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/uspi/keymap.h: -------------------------------------------------------------------------------- 1 | // 2 | // keymap.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014-2016 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_keymap_h 21 | #define _uspi_keymap_h 22 | 23 | #include 24 | 25 | #define PHY_MAX_CODE 127 26 | 27 | #define K_NORMTAB 0 28 | #define K_SHIFTTAB 1 29 | #define K_ALTTAB 2 30 | #define K_ALTSHIFTTAB 3 31 | 32 | typedef enum 33 | { 34 | KeyNone = 0x00, 35 | KeySpace = 0x100, 36 | KeyEscape, 37 | KeyBackspace, 38 | KeyTabulator, 39 | KeyReturn, 40 | KeyInsert, 41 | KeyHome, 42 | KeyPageUp, 43 | KeyDelete, 44 | KeyEnd, 45 | KeyPageDown, 46 | KeyUp, 47 | KeyDown, 48 | KeyLeft, 49 | KeyRight, 50 | KeyF1, 51 | KeyF2, 52 | KeyF3, 53 | KeyF4, 54 | KeyF5, 55 | KeyF6, 56 | KeyF7, 57 | KeyF8, 58 | KeyF9, 59 | KeyF10, 60 | KeyF11, 61 | KeyF12, 62 | KeyApplication, 63 | KeyCapsLock, 64 | KeyPrintScreen, 65 | KeyScrollLock, 66 | KeyPause, 67 | KeyNumLock, 68 | KeyKP_Divide, 69 | KeyKP_Multiply, 70 | KeyKP_Subtract, 71 | KeyKP_Add, 72 | KeyKP_Enter, 73 | KeyKP_1, 74 | KeyKP_2, 75 | KeyKP_3, 76 | KeyKP_4, 77 | KeyKP_5, 78 | KeyKP_6, 79 | KeyKP_7, 80 | KeyKP_8, 81 | KeyKP_9, 82 | KeyKP_0, 83 | KeyKP_Center, 84 | KeyKP_Comma, 85 | KeyKP_Period, 86 | KeyMaxCode 87 | } 88 | TSpecialKey; 89 | 90 | typedef enum 91 | { 92 | ActionSwitchCapsLock = KeyMaxCode, 93 | ActionSwitchNumLock, 94 | ActionSwitchScrollLock, 95 | ActionSelectConsole1, 96 | ActionSelectConsole2, 97 | ActionSelectConsole3, 98 | ActionSelectConsole4, 99 | ActionSelectConsole5, 100 | ActionSelectConsole6, 101 | ActionSelectConsole7, 102 | ActionSelectConsole8, 103 | ActionSelectConsole9, 104 | ActionSelectConsole10, 105 | ActionSelectConsole11, 106 | ActionSelectConsole12, 107 | ActionShutdown, 108 | ActionNone 109 | } 110 | TSpecialAction; 111 | 112 | typedef struct TKeyMap 113 | { 114 | u16 m_KeyMap[PHY_MAX_CODE+1][K_ALTSHIFTTAB+1]; 115 | 116 | boolean m_bCapsLock; 117 | boolean m_bNumLock; 118 | boolean m_bScrollLock; 119 | } 120 | TKeyMap; 121 | 122 | void KeyMap (TKeyMap *pThis); 123 | void _KeyMap (TKeyMap *pThis); 124 | 125 | boolean KeyMapClearTable (TKeyMap *pThis, u8 nTable); 126 | boolean KeyMapSetEntry (TKeyMap *pThis, u8 nTable, u8 nPhyCode, u16 nValue); 127 | 128 | u16 KeyMapTranslate (TKeyMap *pThis, u8 nPhyCode, u8 nModifiers); 129 | const char *KeyMapGetString (TKeyMap *pThis, u16 nKeyCode, u8 nModifiers, char Buffer[2]); 130 | 131 | u8 KeyMapGetLEDStatus (TKeyMap *pThis); 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /include/uspi/keymap_de.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/include/uspi/keymap_de.h -------------------------------------------------------------------------------- /include/uspi/keymap_es.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/include/uspi/keymap_es.h -------------------------------------------------------------------------------- /include/uspi/keymap_fr.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/include/uspi/keymap_fr.h -------------------------------------------------------------------------------- /include/uspi/keymap_it.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/include/uspi/keymap_it.h -------------------------------------------------------------------------------- /include/uspi/keymap_uk.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/include/uspi/keymap_uk.h -------------------------------------------------------------------------------- /include/uspi/keymap_us.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/include/uspi/keymap_us.h -------------------------------------------------------------------------------- /include/uspi/lan7800.h: -------------------------------------------------------------------------------- 1 | // 2 | // lan7800.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2018 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_lan7800_h 21 | #define _uspi_lan7800_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #define FRAME_BUFFER_SIZE 1600 29 | 30 | typedef struct TLAN7800Device 31 | { 32 | TUSBDevice m_USBDevice; 33 | 34 | TUSBEndpoint *m_pEndpointBulkIn; 35 | TUSBEndpoint *m_pEndpointBulkOut; 36 | 37 | TMACAddress m_MACAddress; 38 | 39 | u8 *m_pTxBuffer; 40 | } 41 | TLAN7800Device; 42 | 43 | void LAN7800Device (TLAN7800Device *pThis, TUSBDevice *pDevice); 44 | void _LAN7800Device (TLAN7800Device *pThis); 45 | 46 | boolean LAN7800DeviceConfigure (TUSBDevice *pUSBDevice); 47 | 48 | TMACAddress *LAN7800DeviceGetMACAddress (TLAN7800Device *pThis); 49 | 50 | boolean LAN7800DeviceSendFrame (TLAN7800Device *pThis, const void *pBuffer, unsigned nLength); 51 | 52 | // pBuffer must have size FRAME_BUFFER_SIZE 53 | boolean LAN7800DeviceReceiveFrame (TLAN7800Device *pThis, void *pBuffer, unsigned *pResultLength); 54 | 55 | // returns TRUE if PHY link is up 56 | boolean LAN7800DeviceIsLinkUp (TLAN7800Device *pThis); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/uspi/macaddress.h: -------------------------------------------------------------------------------- 1 | // 2 | // macaddress.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_macaddress_h 21 | #define _uspi_macaddress_h 22 | 23 | #include 24 | #include 25 | 26 | #define MAC_ADDRESS_SIZE 6 27 | 28 | typedef struct TMACAddress 29 | { 30 | boolean m_bValid; 31 | 32 | u8 m_Address[MAC_ADDRESS_SIZE]; 33 | } 34 | TMACAddress; 35 | 36 | void MACAddress (TMACAddress *pThis); 37 | void MACAddress2 (TMACAddress *pThis, const u8 *pAddress); 38 | void _MACAddress (TMACAddress *pThis); 39 | 40 | boolean MACAddressIsEqual (TMACAddress *pThis, TMACAddress *pAddress2); 41 | 42 | void MACAddressSet (TMACAddress *pThis, const u8 *pAddress); 43 | void MACAddressSetBroadcast (TMACAddress *pThis); 44 | const u8 *MACAddressGet (TMACAddress *pThis); 45 | void MACAddressCopyTo (TMACAddress *pThis, u8 *pBuffer); 46 | 47 | boolean MACAddressIsBroadcast (TMACAddress *pThis); 48 | unsigned MACAddressGetSize (TMACAddress *pThis); 49 | 50 | void MACAddressFormat (TMACAddress *pThis, TString *pString); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/uspi/macros.h: -------------------------------------------------------------------------------- 1 | // 2 | // macros.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_macros_h 21 | #define _uspi_macros_h 22 | 23 | #define PACKED __attribute__ ((packed)) 24 | #define ALIGN(n) __attribute__ ((aligned (n))) 25 | #define NOOPT __attribute__ ((optimize (0))) 26 | #define MAXOPT __attribute__ ((optimize (3))) 27 | 28 | // big endian (to be used for constants only) 29 | #define BE(value) ((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/uspi/smsc951x.h: -------------------------------------------------------------------------------- 1 | // 2 | // smsc951x.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_smsc951x_h 21 | #define _uspi_smsc951x_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define FRAME_BUFFER_SIZE 1600 30 | 31 | typedef struct TSMSC951xDevice 32 | { 33 | TUSBDevice m_USBDevice; 34 | 35 | TUSBEndpoint *m_pEndpointBulkIn; 36 | TUSBEndpoint *m_pEndpointBulkOut; 37 | 38 | TMACAddress m_MACAddress; 39 | 40 | u8 *m_pTxBuffer; 41 | } 42 | TSMSC951xDevice; 43 | 44 | void SMSC951xDevice (TSMSC951xDevice *pThis, TUSBDevice *pDevice); 45 | void _SMSC951xDevice (TSMSC951xDevice *pThis); 46 | 47 | boolean SMSC951xDeviceConfigure (TUSBDevice *pUSBDevice); 48 | 49 | TMACAddress *SMSC951xDeviceGetMACAddress (TSMSC951xDevice *pThis); 50 | 51 | boolean SMSC951xDeviceSendFrame (TSMSC951xDevice *pThis, const void *pBuffer, unsigned nLength); 52 | 53 | // pBuffer must have size FRAME_BUFFER_SIZE 54 | boolean SMSC951xDeviceReceiveFrame (TSMSC951xDevice *pThis, void *pBuffer, unsigned *pResultLength); 55 | 56 | // private: 57 | boolean SMSC951xDeviceWriteReg (TSMSC951xDevice *pThis, u32 nIndex, u32 nValue); 58 | boolean SMSC951xDeviceReadReg (TSMSC951xDevice *pThis, u32 nIndex, u32 *pValue); 59 | 60 | #ifndef NDEBUG 61 | void SMSC951xDeviceDumpReg (TSMSC951xDevice *pThis, const char *pName, u32 nIndex); 62 | void SMSC951xDeviceDumpRegs (TSMSC951xDevice *pThis); 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /include/uspi/stdarg.h: -------------------------------------------------------------------------------- 1 | // 2 | // stdarg.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_stdarg_h 21 | #define _uspi_stdarg_h 22 | 23 | typedef __builtin_va_list va_list; 24 | 25 | #define va_start(arg, last) __builtin_va_start (arg, last) 26 | #define va_end(arg) __builtin_va_end (arg) 27 | #define va_arg(arg, type) __builtin_va_arg (arg, type) 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/uspi/string.h: -------------------------------------------------------------------------------- 1 | // 2 | // string.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_string_h 21 | #define _uspi_string_h 22 | 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | 31 | typedef struct TString 32 | { 33 | char *m_pBuffer; 34 | unsigned m_nSize; 35 | char *m_pInPtr; 36 | } 37 | TString; 38 | 39 | void String (TString *pThis); 40 | void String2 (TString *pThis, const char *pString); 41 | void _String (TString *pThis); 42 | 43 | const char *StringGet (TString *pThis); 44 | const char *StringSet (TString *pThis, const char *pString); 45 | 46 | size_t StringGetLength (TString *pThis); 47 | 48 | void StringAppend (TString *pThis, const char *pString); 49 | int StringCompare (TString *pThis, const char *pString); 50 | int StringFind (TString *pThis, char chChar); // returns index or -1 if not found 51 | 52 | void StringFormat (TString *pThis, const char *pFormat, ...); // supports only a small subset of printf(3) 53 | void StringFormatV (TString *pThis, const char *pFormat, va_list Args); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/uspi/synchronize.h: -------------------------------------------------------------------------------- 1 | // 2 | // synchronize.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014-2015 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_synchronize_h 21 | #define _uspi_synchronize_h 22 | 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | // 31 | // Interrupt synchronization 32 | // 33 | void uspi_EnterCritical (void); // disable interrupts (nested calls possible) 34 | void uspi_LeaveCritical (void); // enable interrupts (nested calls possible) 35 | 36 | #if RASPPI == 1 37 | 38 | // 39 | // Cache control 40 | // 41 | #define InvalidateInstructionCache() \ 42 | __asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0) : "memory") 43 | #define FlushPrefetchBuffer() __asm volatile ("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory") 44 | #define FlushBranchTargetCache() \ 45 | __asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0) : "memory") 46 | #define InvalidateDataCache() __asm volatile ("mcr p15, 0, %0, c7, c6, 0" : : "r" (0) : "memory") 47 | #define CleanDataCache() __asm volatile ("mcr p15, 0, %0, c7, c10, 0" : : "r" (0) : "memory") 48 | 49 | void uspi_CleanAndInvalidateDataCacheRange (u32 nAddress, u32 nLength) MAXOPT; 50 | 51 | // 52 | // Barriers 53 | // 54 | #define DataSyncBarrier() __asm volatile ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory") 55 | #define DataMemBarrier() __asm volatile ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory") 56 | 57 | #define InstructionSyncBarrier() FlushPrefetchBuffer() 58 | #define InstructionMemBarrier() FlushPrefetchBuffer() 59 | 60 | #else 61 | 62 | // 63 | // Cache control 64 | // 65 | #define InvalidateInstructionCache() \ 66 | __asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0) : "memory") 67 | #define FlushPrefetchBuffer() __asm volatile ("isb" ::: "memory") 68 | #define FlushBranchTargetCache() \ 69 | __asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0) : "memory") 70 | 71 | void uspi_CleanAndInvalidateDataCacheRange (u32 nAddress, u32 nLength) MAXOPT; 72 | 73 | // 74 | // Barriers 75 | // 76 | #define DataSyncBarrier() __asm volatile ("dsb" ::: "memory") 77 | #define DataMemBarrier() __asm volatile ("dmb" ::: "memory") 78 | 79 | #define InstructionSyncBarrier() __asm volatile ("isb" ::: "memory") 80 | #define InstructionMemBarrier() __asm volatile ("isb" ::: "memory") 81 | 82 | #endif 83 | 84 | #define CompilerBarrier() __asm volatile ("" ::: "memory") 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /include/uspi/types.h: -------------------------------------------------------------------------------- 1 | // 2 | // types.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_types_h 21 | #define _uspi_types_h 22 | 23 | typedef unsigned char u8; 24 | typedef unsigned short u16; 25 | typedef unsigned int u32; 26 | typedef unsigned long long u64; 27 | 28 | typedef char s8; 29 | typedef short s16; 30 | typedef int s32; 31 | 32 | typedef int boolean; 33 | #define FALSE 0 34 | #define TRUE 1 35 | 36 | typedef unsigned long size_t; 37 | typedef long ssize_t; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/uspi/usbconfigparser.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbconfigparser.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbconfigparser_h 21 | #define _uspi_usbconfigparser_h 22 | 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | typedef struct TUSBConfigurationParser 31 | { 32 | const TUSBDescriptor *m_pBuffer; 33 | unsigned m_nBufLen; 34 | boolean m_bValid; 35 | const TUSBDescriptor *m_pEndPosition; 36 | const TUSBDescriptor *m_pCurrentPosition; 37 | const TUSBDescriptor *m_pErrorPosition; 38 | } 39 | TUSBConfigurationParser; 40 | 41 | void USBConfigurationParser (TUSBConfigurationParser *pThis, const void *pBuffer, unsigned nBufLen); 42 | void _USBConfigurationParser (TUSBConfigurationParser *pThis); 43 | 44 | boolean USBConfigurationParserIsValid (TUSBConfigurationParser *pThis); 45 | 46 | const TUSBDescriptor *USBConfigurationParserGetDescriptor (TUSBConfigurationParser *pThis, u8 ucType); // returns 0 if not found 47 | 48 | void USBConfigurationParserError (TUSBConfigurationParser *pThis, const char *pSource); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /include/uspi/usbdevice.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbdevice.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbdevice_h 21 | #define _uspi_usbdevice_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | typedef enum // do not change this order 34 | { 35 | DeviceNameVendor, 36 | DeviceNameDevice, 37 | DeviceNameInterface, 38 | DeviceNameUnknown 39 | } 40 | TDeviceNameSelector; 41 | 42 | struct TDWHCIDevice; 43 | struct TUSBEndpoint; 44 | 45 | typedef struct TUSBDevice 46 | { 47 | boolean (*Configure) (struct TUSBDevice *pThis); 48 | 49 | struct TDWHCIDevice *m_pHost; 50 | 51 | u8 m_ucAddress; 52 | TUSBSpeed m_Speed; 53 | struct TUSBEndpoint *m_pEndpoint0; 54 | 55 | u8 m_ucHubAddress; 56 | u8 m_ucHubPortNumber; 57 | 58 | TUSBDeviceDescriptor *m_pDeviceDesc; 59 | TUSBConfigurationDescriptor *m_pConfigDesc; 60 | 61 | TUSBConfigurationParser *m_pConfigParser; 62 | 63 | TUSBString m_ManufacturerString; 64 | TUSBString m_ProductString; 65 | } 66 | TUSBDevice; 67 | 68 | void USBDevice (TUSBDevice *pThis, struct TDWHCIDevice *pHost, TUSBSpeed Speed, u8 ucHubAddress, u8 ucHubPortNumber); 69 | void USBDeviceCopy (TUSBDevice *pThis, TUSBDevice *pDevice); 70 | void _USBDevice (TUSBDevice *pThis); 71 | 72 | boolean USBDeviceInitialize (TUSBDevice *pThis); // onto address state (phase 1) 73 | boolean USBDeviceConfigure (TUSBDevice *pThis); // onto configured state (phase 2) 74 | 75 | TString *USBDeviceGetName (TUSBDevice *pThis, TDeviceNameSelector Selector); // string deleted by caller 76 | 77 | u8 USBDeviceGetAddress (TUSBDevice *pThis); 78 | TUSBSpeed USBDeviceGetSpeed (TUSBDevice *pThis); 79 | 80 | u8 USBDeviceGetHubAddress (TUSBDevice *pThis); 81 | u8 USBDeviceGetHubPortNumber (TUSBDevice *pThis); 82 | 83 | struct TUSBEndpoint *USBDeviceGetEndpoint0 (TUSBDevice *pThis); 84 | struct TDWHCIDevice *USBDeviceGetHost (TUSBDevice *pThis); 85 | 86 | const TUSBDeviceDescriptor *USBDeviceGetDeviceDescriptor (TUSBDevice *pThis); 87 | const TUSBConfigurationDescriptor *USBDeviceGetConfigurationDescriptor (TUSBDevice *pThis); // default config 88 | 89 | // get next sub descriptor of ucType from configuration descriptor 90 | const TUSBDescriptor *USBDeviceGetDescriptor (TUSBDevice *pThis, u8 ucType); // returns 0 if not found 91 | void USBDeviceConfigurationError (TUSBDevice *pThis, const char *pSource); 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /include/uspi/usbdevicefactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbdevicefactory.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbdevicefactory_h 21 | #define _uspi_usbdevicefactory_h 22 | 23 | #include 24 | #include 25 | 26 | TUSBDevice *USBDeviceFactoryGetDevice (TUSBDevice *pParent); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /include/uspi/usbendpoint.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbendpoint.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbendpoint_h 21 | #define _uspi_usbendpoint_h 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | typedef enum 32 | { 33 | EndpointTypeControl, 34 | EndpointTypeBulk, 35 | EndpointTypeInterrupt, 36 | EndpointTypeIsochronous 37 | } 38 | TEndpointType; 39 | 40 | typedef struct TUSBEndpoint 41 | { 42 | TUSBDevice *m_pDevice; 43 | u8 m_ucNumber; 44 | TEndpointType m_Type; 45 | boolean m_bDirectionIn; 46 | u32 m_nMaxPacketSize; 47 | unsigned m_nInterval; // Milliseconds 48 | TUSBPID m_NextPID; 49 | } 50 | TUSBEndpoint; 51 | 52 | void USBEndpoint (TUSBEndpoint *pThis, TUSBDevice *pDevice); // control endpoint 0 53 | void USBEndpoint2 (TUSBEndpoint *pThis, TUSBDevice *pDevice, const TUSBEndpointDescriptor *pDesc); 54 | void USBEndpointCopy (TUSBEndpoint *pThis, TUSBEndpoint *pEndpoint, TUSBDevice *pDevice); 55 | void _USBEndpoint (TUSBEndpoint *pThis); 56 | 57 | TUSBDevice *USBEndpointGetDevice (TUSBEndpoint *pThis); 58 | 59 | u8 USBEndpointGetNumber (TUSBEndpoint *pThis); 60 | TEndpointType USBEndpointGetType (TUSBEndpoint *pThis); 61 | boolean USBEndpointIsDirectionIn (TUSBEndpoint *pThis); 62 | 63 | void USBEndpointSetMaxPacketSize (TUSBEndpoint *pThis, u32 nMaxPacketSize); 64 | u32 USBEndpointGetMaxPacketSize (TUSBEndpoint *pThis); 65 | 66 | unsigned USBEndpointGetInterval (TUSBEndpoint *pThis); // Milliseconds 67 | 68 | TUSBPID USBEndpointGetNextPID (TUSBEndpoint *pThis, boolean bStatusStage); 69 | void USBEndpointSkipPID (TUSBEndpoint *pThis, unsigned nPackets, boolean bStatusStage); 70 | void USBEndpointResetPID (TUSBEndpoint *pThis); 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /include/uspi/usbgamepad.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbgamepad.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // Copyright (C) 2014 M. Maccaferri 7 | // 8 | // This program is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | #ifndef _usbgamepad_h 22 | #define _usbgamepad_h 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | typedef struct TUSBGamePadDevice 32 | { 33 | TUSBDevice m_USBDevice; 34 | unsigned m_nDeviceIndex; 35 | 36 | u8 m_ucInterfaceNumber; 37 | u8 m_ucAlternateSetting; 38 | 39 | TUSBEndpoint *m_pEndpointIn; 40 | TUSBEndpoint *m_pEndpointOut; 41 | 42 | USPiGamePadState m_State; 43 | TGamePadStatusHandler *m_pStatusHandler; 44 | 45 | u16 m_usReportDescriptorLength; 46 | u8 *m_pHIDReportDescriptor; 47 | 48 | TUSBRequest *m_pURB; 49 | u8 *m_pReportBuffer; 50 | u16 m_nReportSize; 51 | } 52 | TUSBGamePadDevice; 53 | 54 | void USBGamePadDevice (TUSBGamePadDevice *pThis, TUSBDevice *pDevice); 55 | void _CUSBGamePadDevice (TUSBGamePadDevice *pThis); 56 | 57 | boolean USBGamePadDeviceConfigure (TUSBDevice *pUSBDevice); 58 | 59 | void USBGamePadDeviceGetReport (TUSBGamePadDevice *pThis); 60 | void USBGamePadDeviceRegisterStatusHandler (TUSBGamePadDevice *pThis, TGamePadStatusHandler *pStatusHandler); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /include/uspi/usbhid.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbhid.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbhid_h 21 | #define _uspi_usbhid_h 22 | 23 | #include 24 | 25 | // Class-specific requests 26 | #define GET_REPORT 0x01 27 | #define GET_IDLE 0x02 28 | #define GET_PROTOCOL 0x03 29 | #define SET_REPORT 0x09 30 | #define SET_IDLE 0x0A 31 | #define SET_PROTOCOL 0x0B 32 | 33 | // Class-specific descriptors 34 | #define DESCRIPTOR_HID 0x21 35 | #define DESCRIPTOR_REPORT 0x22 36 | 37 | // Protocol IDs 38 | #define BOOT_PROTOCOL 0x00 39 | #define REPORT_PROTOCOL 0x01 40 | 41 | // Report types 42 | #define REPORT_TYPE_INPUT 0x01 43 | #define REPORT_TYPE_OUTPUT 0x02 44 | #define REPORT_TYPE_FEATURE 0x03 45 | 46 | typedef struct TUSBHIDDescriptor 47 | { 48 | unsigned char bLength; 49 | unsigned char bDescriptorType; 50 | unsigned short bcdHID; 51 | unsigned char bCountryCode; 52 | unsigned char bNumDescriptors; 53 | unsigned char bReportDescriptorType; 54 | unsigned short wReportDescriptorLength; 55 | } 56 | PACKED TUSBHIDDescriptor; 57 | 58 | // Modifiers (boot protocol) 59 | #define LCTRL (1 << 0) 60 | #define LSHIFT (1 << 1) 61 | #define ALT (1 << 2) 62 | #define LWIN (1 << 3) 63 | #define RCTRL (1 << 4) 64 | #define RSHIFT (1 << 5) 65 | #define ALTGR (1 << 6) 66 | #define RWIN (1 << 7) 67 | 68 | // LEDs (boot protocol) 69 | #define LED_NUM_LOCK (1 << 0) 70 | #define LED_CAPS_LOCK (1 << 1) 71 | #define LED_SCROLL_LOCK (1 << 2) 72 | 73 | // Mouse buttons (boot protocol) 74 | #define USBHID_BUTTON1 (1 << 0) 75 | #define USBHID_BUTTON2 (1 << 1) 76 | #define USBHID_BUTTON3 (1 << 2) 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /include/uspi/usbhostcontroller.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbhostcontroller.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbhostcontroller_h 21 | #define _uspi_usbhostcontroller_h 22 | 23 | #include 24 | 25 | #define TUSBHostController TDWHCIDevice // alias 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/uspi/usbhub.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbhub.h 3 | // 4 | // Definitions for USB hubs 5 | // 6 | // USPi - An USB driver for Raspberry Pi written in C 7 | // Copyright (C) 2014 R. Stange 8 | // 9 | // This program is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published by 11 | // the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This program is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | #ifndef _uspi_usbhub_h 23 | #define _uspi_usbhub_h 24 | 25 | #include 26 | 27 | // Configuration 28 | #define USB_HUB_MAX_PORTS 8 // TODO 29 | 30 | // Device Class 31 | #define USB_DEVICE_CLASS_HUB 9 32 | 33 | // Class-specific Requests 34 | #define RESET_TT 9 35 | 36 | // Descriptor Type 37 | #define DESCRIPTOR_HUB 0x29 38 | 39 | // Feature Selectors 40 | #define PORT_RESET 4 41 | #define PORT_POWER 8 42 | 43 | // Hub Descriptor 44 | typedef struct TUSBHubDescriptor 45 | { 46 | unsigned char bDescLength; 47 | unsigned char bDescriptorType; 48 | unsigned char bNbrPorts; 49 | unsigned short wHubCharacteristics; 50 | #define HUB_POWER_MODE(reg) ((reg) & 3) 51 | #define HUB_POWER_MODE_GANGED 0 52 | #define HUB_POWER_MODE_INDIVIDUAL 1 53 | #define HUB_TT_THINK_TIME(reg) (((reg) >> 5) & 3) 54 | unsigned char bPwrOn2PwrGood; 55 | unsigned char bHubContrCurrent; 56 | unsigned char DeviceRemoveable[1]; // max. 8 ports 57 | unsigned char PortPwrCtrlMask[1]; // max. 8 ports 58 | } 59 | PACKED TUSBHubDescriptor; 60 | 61 | typedef struct TUSBHubStatus 62 | { 63 | unsigned short wHubStatus; 64 | #define HUB_LOCAL_POWER_LOST__MASK (1 << 0) 65 | #define HUB_OVER_CURRENT__MASK (1 << 1) 66 | unsigned short wHubChange; 67 | #define C_HUB_LOCAL_POWER_LOST__MASK (1 << 0) 68 | #define C_HUB_OVER_CURRENT__MASK (1 << 1) 69 | } 70 | PACKED TUSBHubStatus; 71 | 72 | typedef struct TUSBPortStatus 73 | { 74 | unsigned short wPortStatus; 75 | #define PORT_CONNECTION__MASK (1 << 0) 76 | #define PORT_ENABLE__MASK (1 << 1) 77 | #define PORT_OVER_CURRENT__MASK (1 << 3) 78 | #define PORT_RESET__MASK (1 << 4) 79 | #define PORT_POWER__MASK (1 << 8) 80 | #define PORT_LOW_SPEED__MASK (1 << 9) 81 | #define PORT_HIGH_SPEED__MASK (1 << 10) 82 | unsigned short wChangeStatus; 83 | } 84 | PACKED TUSBPortStatus; 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /include/uspi/usbkeyboard.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbkeyboard.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _usbkeyboard_h 21 | #define _usbkeyboard_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define BOOT_REPORT_SIZE 8 30 | 31 | typedef void TKeyPressedHandler (const char *pString); 32 | typedef void TSelectConsoleHandler (unsigned nConsole); 33 | typedef void TShutdownHandler (void); 34 | 35 | // The raw handler is called when the keyboard sends a status report (on status change and/or continously). 36 | typedef void TKeyStatusHandlerRaw (unsigned char ucModifiers, // see usbhid.h 37 | const unsigned char RawKeys[6]); // key code or 0 in each byte 38 | 39 | typedef struct TUSBKeyboardDevice 40 | { 41 | TUSBDevice m_USBDevice; 42 | 43 | u8 m_ucInterfaceNumber; 44 | u8 m_ucAlternateSetting; 45 | 46 | TUSBEndpoint *m_pReportEndpoint; 47 | 48 | TKeyPressedHandler *m_pKeyPressedHandler; 49 | TSelectConsoleHandler *m_pSelectConsoleHandler; 50 | TShutdownHandler *m_pShutdownHandler; 51 | TKeyStatusHandlerRaw *m_pKeyStatusHandlerRaw; 52 | 53 | TUSBRequest *m_pURB; 54 | u8 *m_pReportBuffer; 55 | 56 | u8 m_ucLastPhyCode; 57 | unsigned m_hTimer; 58 | 59 | TKeyMap m_KeyMap; 60 | } 61 | TUSBKeyboardDevice; 62 | 63 | void USBKeyboardDevice (TUSBKeyboardDevice *pThis, TUSBDevice *pDevice); 64 | void _CUSBKeyboardDevice (TUSBKeyboardDevice *pThis); 65 | 66 | boolean USBKeyboardDeviceConfigure (TUSBDevice *pUSBDevice); 67 | 68 | // cooked mode 69 | void USBKeyboardDeviceRegisterKeyPressedHandler (TUSBKeyboardDevice *pThis, TKeyPressedHandler *pKeyPressedHandler); 70 | void USBKeyboardDeviceRegisterSelectConsoleHandler (TUSBKeyboardDevice *pThis, TSelectConsoleHandler *pSelectConsoleHandler); 71 | void USBKeyboardDeviceRegisterShutdownHandler (TUSBKeyboardDevice *pThis, TShutdownHandler *pShutdownHandler); 72 | 73 | // raw mode (if this handler is registered the others are ignored) 74 | void USBKeyboardDeviceRegisterKeyStatusHandlerRaw (TUSBKeyboardDevice *pThis, TKeyStatusHandlerRaw *pKeyStatusHandlerRaw); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /include/uspi/usbmassdevice.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbmassdevice.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbmassdevice_h 21 | #define _uspi_usbmassdevice_h 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #define UMSD_BLOCK_SIZE 512 32 | #define UMSD_BLOCK_MASK (UMSD_BLOCK_SIZE-1) 33 | #define UMSD_BLOCK_SHIFT 9 34 | 35 | #define UMSD_MAX_OFFSET 0x1FFFFFFFFFFULL // 2TB 36 | 37 | typedef struct TUSBBulkOnlyMassStorageDevice 38 | { 39 | TUSBDevice m_USBDevice; 40 | 41 | TUSBEndpoint *m_pEndpointIn; 42 | TUSBEndpoint *m_pEndpointOut; 43 | 44 | unsigned m_nCWBTag; 45 | unsigned m_nBlockCount; 46 | unsigned long long m_ullOffset; 47 | } 48 | TUSBBulkOnlyMassStorageDevice; 49 | 50 | void USBBulkOnlyMassStorageDevice (TUSBBulkOnlyMassStorageDevice *pThis, TUSBDevice *pDevice); 51 | void _USBBulkOnlyMassStorageDevice (TUSBBulkOnlyMassStorageDevice *pThis); 52 | 53 | boolean USBBulkOnlyMassStorageDeviceConfigure (TUSBDevice *pUSBDevice); 54 | 55 | int USBBulkOnlyMassStorageDeviceRead (TUSBBulkOnlyMassStorageDevice *pThis, void *pBuffer, unsigned nCount); 56 | int USBBulkOnlyMassStorageDeviceWrite (TUSBBulkOnlyMassStorageDevice *pThis, const void *pBuffer, unsigned nCount); 57 | 58 | unsigned long long USBBulkOnlyMassStorageDeviceSeek (TUSBBulkOnlyMassStorageDevice *pThis, unsigned long long ullOffset); 59 | 60 | unsigned USBBulkOnlyMassStorageDeviceGetCapacity (TUSBBulkOnlyMassStorageDevice *pThis); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /include/uspi/usbmidi.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbmidi.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2016 R. Stange 6 | // Copyright (C) 2016 J. Otto 7 | // 8 | // This program is free software: you can redistribute it and/or modify 9 | // it under the terms of the GNU General Public License as published by 10 | // the Free Software Foundation, either version 3 of the License, or 11 | // (at your option) any later version. 12 | // 13 | // This program is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | // GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with this program. If not, see . 20 | // 21 | #ifndef _usbmidi_h 22 | #define _usbmidi_h 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | typedef void TMIDIPacketHandler(unsigned nCable, unsigned nLength, u8 *pPacket); 30 | 31 | typedef struct TUSBMIDIDevice 32 | { 33 | TUSBDevice m_USBDevice; 34 | 35 | TUSBEndpoint *m_pEndpointIn; 36 | 37 | TMIDIPacketHandler *m_pPacketHandler; 38 | 39 | TUSBRequest *m_pURB; 40 | u16 m_usBufferSize; 41 | u8 *m_pPacketBuffer; 42 | } 43 | TUSBMIDIDevice; 44 | 45 | void USBMIDIDevice (TUSBMIDIDevice *pThis, TUSBDevice *pDevice); 46 | void _CUSBMIDIDevice (TUSBMIDIDevice *pThis); 47 | 48 | boolean USBMIDIDeviceConfigure (TUSBDevice *pUSBDevice); 49 | 50 | void USBMIDIDeviceRegisterPacketHandler (TUSBMIDIDevice *pThis, TMIDIPacketHandler *pPacketHandler); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/uspi/usbmouse.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbmouse.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _usbmouse_h 21 | #define _usbmouse_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #define MOUSE_BOOT_REPORT_SIZE 3 29 | 30 | typedef void TMouseStatusHandler (unsigned nButtons, int nDisplacementX, int nDisplacementY); 31 | 32 | typedef struct TUSBMouseDevice 33 | { 34 | TUSBDevice m_USBDevice; 35 | 36 | u8 m_ucInterfaceNumber; 37 | u8 m_ucAlternateSetting; 38 | 39 | TUSBEndpoint *m_pReportEndpoint; 40 | 41 | TMouseStatusHandler *m_pStatusHandler; 42 | 43 | TUSBRequest *m_pURB; 44 | u8 *m_pReportBuffer; 45 | } 46 | TUSBMouseDevice; 47 | 48 | void USBMouseDevice (TUSBMouseDevice *pThis, TUSBDevice *pDevice); 49 | void _CUSBMouseDevice (TUSBMouseDevice *pThis); 50 | 51 | boolean USBMouseDeviceConfigure (TUSBDevice *pUSBDevice); 52 | 53 | void USBMouseDeviceRegisterStatusHandler (TUSBMouseDevice *pThis, TMouseStatusHandler *pStatusHandler); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/uspi/usbrequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbrequest.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbrequest_h 21 | #define _uspi_usbrequest_h 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct TUSBRequest; 32 | 33 | typedef void TURBCompletionRoutine (struct TUSBRequest *pURB, void *pParam, void *pContext); 34 | 35 | typedef struct TUSBRequest // URB 36 | { 37 | TUSBEndpoint *m_pEndpoint; 38 | 39 | TSetupData *m_pSetupData; 40 | void *m_pBuffer; 41 | u32 m_nBufLen; 42 | 43 | int m_bStatus; 44 | u32 m_nResultLen; 45 | 46 | TURBCompletionRoutine *m_pCompletionRoutine; 47 | void *m_pCompletionParam; 48 | void *m_pCompletionContext; 49 | } 50 | TUSBRequest; 51 | 52 | void USBRequest (TUSBRequest *pThis, TUSBEndpoint *pEndpoint, void *pBuffer, u32 nBufLen, TSetupData *pSetupData /* = 0 */); 53 | void _USBRequest (TUSBRequest *pThis); 54 | 55 | TUSBEndpoint *USBRequestGetEndpoint (TUSBRequest *pThis); 56 | 57 | void USBRequestSetStatus (TUSBRequest *pThis, int bStatus); 58 | void USBRequestSetResultLen (TUSBRequest *pThis, u32 nLength); 59 | 60 | int USBRequestGetStatus (TUSBRequest *pThis); 61 | u32 USBRequestGetResultLength (TUSBRequest *pThis); 62 | 63 | TSetupData *USBRequestGetSetupData (TUSBRequest *pThis); 64 | void *USBRequestGetBuffer (TUSBRequest *pThis); 65 | u32 USBRequestGetBufLen (TUSBRequest *pThis); 66 | 67 | void USBRequestSetCompletionRoutine (TUSBRequest *pThis, TURBCompletionRoutine *pRoutine, void *pParam, void *pContext); 68 | void USBRequestCallCompletionRoutine (TUSBRequest *pThis); 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /include/uspi/usbstandardhub.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbstandardhub.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _usbstandardhub_h 21 | #define _usbstandardhub_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | typedef struct TUSBStandardHub 35 | { 36 | TUSBDevice m_USBDevice; 37 | 38 | TUSBHubDescriptor *m_pHubDesc; 39 | 40 | unsigned m_nPorts; 41 | TUSBDevice *m_pDevice[USB_HUB_MAX_PORTS]; 42 | TUSBPortStatus *m_pStatus[USB_HUB_MAX_PORTS]; 43 | } 44 | TUSBStandardHub; 45 | 46 | void USBStandardHub (TUSBStandardHub *pThis, TUSBDevice *pDevice); 47 | void _USBStandardHub (TUSBStandardHub *pThis); 48 | 49 | boolean USBStandardHubInitialize (TUSBStandardHub *pThis); 50 | boolean USBStandardHubConfigure (TUSBDevice *pUSBDevice); 51 | 52 | TString *USBStandardHubGetDeviceNames (TUSBDevice *pDevice); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/uspi/usbstring.h: -------------------------------------------------------------------------------- 1 | // 2 | // usbstring.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_usbstring_h 21 | #define _uspi_usbstring_h 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | struct TUSBDevice; 32 | 33 | typedef struct TUSBString 34 | { 35 | struct TUSBDevice *m_pDevice; 36 | 37 | TUSBStringDescriptor *m_pUSBString; 38 | 39 | TString *m_pString; 40 | } 41 | TUSBString; 42 | 43 | void USBString (TUSBString *pThis, struct TUSBDevice *pDevice); 44 | void USBStringCopy (TUSBString *pThis, TUSBString *pParent); 45 | void _USBString (TUSBString *pThis); 46 | 47 | boolean USBStringGetFromDescriptor (TUSBString *pThis, u8 ucID, u16 usLanguageID); 48 | 49 | const char *USBStringGet (TUSBString *pThis); 50 | 51 | u16 USBStringGetLanguageID (TUSBString *pThis); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /include/uspi/uspilibrary.h: -------------------------------------------------------------------------------- 1 | // 2 | // uspilibrary.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014-2018 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_uspilibrary_h 21 | #define _uspi_uspilibrary_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #define MAX_DEVICES 4 38 | 39 | typedef struct TUSPiLibrary 40 | { 41 | TDeviceNameService NameService; 42 | TDWHCIDevice DWHCI; 43 | TUSBKeyboardDevice *pUKBD1; 44 | TUSBMouseDevice *pUMouse1; 45 | TUSBBulkOnlyMassStorageDevice *pUMSD[MAX_DEVICES]; 46 | TSMSC951xDevice *pEth0; 47 | TLAN7800Device *pEth10; 48 | TUSBGamePadDevice *pUPAD[MAX_DEVICES]; 49 | TUSBMIDIDevice *pMIDI1; 50 | } 51 | TUSPiLibrary; 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /include/uspi/util.h: -------------------------------------------------------------------------------- 1 | // 2 | // util.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspi_util_h 21 | #define _uspi_util_h 22 | 23 | #include 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #ifdef USPI_PROVIDE_MEM_FUNCTIONS 31 | #define memset uspi_memset 32 | #define memcpy uspi_memcpy 33 | #define memcmp uspi_memcmp 34 | #endif 35 | 36 | #ifdef USPI_PROVIDE_STR_FUNCTIONS 37 | #define strlen uspi_strlen 38 | #define strcmp uspi_strcmp 39 | #define strcpy uspi_strcpy 40 | #define strncpy uspi_strncpy 41 | #define strcat uspi_strcat 42 | #endif 43 | 44 | void *memset (void *pBuffer, int nValue, size_t nLength); 45 | 46 | void *memcpy (void *pDest, const void *pSrc, size_t nLength); 47 | 48 | int memcmp (const void *pBuffer1, const void *pBuffer2, size_t nLength); 49 | 50 | size_t strlen (const char *pString); 51 | 52 | int strcmp (const char *pString1, const char *pString2); 53 | 54 | char *strcpy (char *pDest, const char *pSrc); 55 | 56 | char *strncpy (char *pDest, const char *pSrc, size_t nMaxLen); 57 | 58 | char *strcat (char *pDest, const char *pSrc); 59 | 60 | int uspi_char2int (char chValue); // with sign extension 61 | 62 | u16 uspi_le2be16 (u16 usValue); 63 | 64 | u32 uspi_le2be32 (u32 ulValue); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /include/uspienv/memio.h: -------------------------------------------------------------------------------- 1 | // 2 | // memio.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspienv_memio_h 21 | #define _uspienv_memio_h 22 | 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | u32 read32 (u32 nAddress); 30 | 31 | void write32 (u32 nAddress, u32 nValue); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/uspienv/timer.h: -------------------------------------------------------------------------------- 1 | // 2 | // timer.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #ifndef _uspienv_timer_h 21 | #define _uspienv_timer_h 22 | 23 | //#include 24 | //#include 25 | //#include 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #define HZ 100 // ticks per second 33 | 34 | #define MSEC2HZ(msec) ((msec) * HZ / 1000) 35 | 36 | #define KERNEL_TIMERS 20 37 | 38 | typedef void TKernelTimerHandler (unsigned hTimer, void *pParam, void *pContext); 39 | 40 | typedef struct TKernelTimer 41 | { 42 | TKernelTimerHandler *m_pHandler; 43 | unsigned m_nElapsesAt; 44 | void *m_pParam; 45 | void *m_pContext; 46 | } 47 | TKernelTimer; 48 | 49 | typedef struct TTimer 50 | { 51 | //TInterruptSystem *m_pInterruptSystem; 52 | volatile unsigned m_nTicks; 53 | volatile unsigned m_nTime; 54 | volatile TKernelTimer m_KernelTimer[KERNEL_TIMERS]; // TODO: should be linked list 55 | unsigned m_nMsDelay; 56 | unsigned m_nusDelay; 57 | } 58 | TTimer; 59 | 60 | //void Timer (TTimer *pThis, TInterruptSystem *pInterruptSystem); 61 | void TimerEnvInit (TTimer *pThis); 62 | void _Timer (TTimer *pThis); 63 | 64 | boolean TimerInitialize (TTimer *pThis); 65 | 66 | unsigned TimerGetClockTicks (TTimer *pThis); // 1 MHz counter 67 | #define CLOCKHZ 1000000 68 | 69 | unsigned TimerGetTicks (TTimer *pThis); // 1/HZ seconds since system boot 70 | unsigned TimerGetTime (TTimer *pThis); // Seconds since system boot 71 | 72 | // "HH:MM:SS.ss", 0 if Initialize() was not yet called 73 | //TString *TimerGetTimeString (TTimer *pThis); // CString object must be deleted by caller 74 | 75 | // returns timer handle (0 on failure) 76 | unsigned TimerStartKernelTimer (TTimer *pThis, 77 | unsigned nDelay, // in HZ units 78 | TKernelTimerHandler *pHandler, 79 | void *pParam, 80 | void *pContext); 81 | void TimerCancelKernelTimer (TTimer *pThis, unsigned hTimer); 82 | 83 | // when a CTimer object is available better use these methods 84 | void TimerMsDelay (TTimer *pThis, unsigned nMilliSeconds); 85 | void TimerusDelay (TTimer *pThis, unsigned nMicroSeconds); 86 | 87 | TTimer *TimerGet (void); 88 | 89 | // can be used before Timer is constructed 90 | void TimerSimpleMsDelay (unsigned nMilliSeconds); 91 | void TimerSimpleusDelay (unsigned nMicroSeconds); 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /kernel.ld: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * kernel.ld 3 | * by Alex Chadwick 4 | * 5 | * A linker script for generation of raspberry pi kernel images. 6 | ******************************************************************************/ 7 | ENTRY(_start) 8 | 9 | PHYSOFFSET = DEFINED(PHYSOFFSET) ? PHYSOFFSET : 0x80008000; 10 | KERNOFFSET = DEFINED(KERNOFFSET) ? KERNOFFSET : 0xC0008000; 11 | SHIFT = KERNOFFSET - PHYSOFFSET; 12 | 13 | SECTIONS { 14 | /* Link the kernel at this address: "." means the current address */ 15 | /* Must be equal to KERNLINK */ 16 | 17 | /* 18 | * First and formost we need the .init section, containing the code to 19 | * be run first. We allow room for the ATAGs and stack and conform to 20 | * the bootloader's expectation by putting this code at 0x8000. 21 | */ 22 | 23 | .init PHYSOFFSET : { 24 | *(.init) 25 | } 26 | 27 | . = ALIGN(0x100); 28 | INIT_END = .; 29 | . = . + SHIFT; 30 | 31 | /* 32 | * Next we put the rest of the code. 33 | */ 34 | 35 | .text : AT (INIT_END) { 36 | *.c.o(.text) 37 | *(.text .stub .text.*) 38 | } 39 | 40 | /* 41 | * read-only data 42 | */ 43 | .rodata : { 44 | *(.rodata .rodata.*) 45 | } 46 | 47 | /* Adjust the address for the data segment to the next page */ 48 | . = ALIGN(0x1000); 49 | 50 | /* 51 | * Next we put the data. 52 | */ 53 | .data : { 54 | *(.data) 55 | *.c.o(*) 56 | } 57 | 58 | .bss : { 59 | *(.bss) 60 | } 61 | 62 | PROVIDE(end = .); 63 | 64 | /* 65 | * Finally comes everything else. A fun trick here is to put all other 66 | * sections into this section, which will be discarded by default. 67 | */ 68 | /DISCARD/ : { 69 | *(.eh_frame .note.GNU-stack) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /loader.S: -------------------------------------------------------------------------------- 1 | /* 2 | * loader.S 3 | * 4 | * Created on: Feb 11, 2017 5 | * Author: Mahdi Amiri 6 | */ 7 | 8 | .text 9 | .globl _start 10 | _start: 11 | b loader_start /* branch to the code */ 12 | b loader_sleep // undefined 13 | b loader_sleep // svc 14 | b loader_sleep // prefetch 15 | b loader_sleep // abort 16 | b loader_sleep // hypervisor 17 | b loader_sleep // irq 18 | b loader_sleep // fiq 19 | 20 | 21 | .balign 4 22 | loader_sleep: 23 | wfe 24 | b loader_sleep 25 | 26 | loader_start: 27 | // Switch to SVC mode, all interrupts disabled 28 | .set PSR_MODE_SVC, 0x13 29 | .set PSR_MODE_IRQ_DISABLED, (1<<7) 30 | .set PSR_MODE_FIQ_DISABLED, (1<<6) 31 | msr cpsr_c, #(PSR_MODE_SVC + PSR_MODE_FIQ_DISABLED + PSR_MODE_IRQ_DISABLED) 32 | 33 | // Set all CPUs to wait except the primary CPU 34 | //mrc p15, 0, r0, c0, c0, 5 35 | //ands r0, r0, #0x03 36 | //bne loader_sleep 37 | 38 | mov pc, #0x8000 39 | 40 | .data 41 | .align 4 42 | _data_start: 43 | .incbin "kernel7.bin" 44 | _data_end: 45 | -------------------------------------------------------------------------------- /loader.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | SECTIONS { 3 | .text 0x0 : { 4 | * (.text); 5 | } 6 | .data 0x8000 : { 7 | * (.data); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /source/LICENSE: -------------------------------------------------------------------------------- 1 | The xv6 software is: 2 | 3 | Copyright (c) 2006-2009 Frans Kaashoek, Robert Morris, Russ Cox, 4 | Massachusetts Institute of Technology 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | -------------------------------------------------------------------------------- /source/bio.c: -------------------------------------------------------------------------------- 1 | // Buffer cache. 2 | // 3 | // The buffer cache is a linked list of buf structures holding 4 | // cached copies of disk block contents. Caching disk blocks 5 | // in memory reduces the number of disk reads and also provides 6 | // a synchronization point for disk blocks used by multiple processes. 7 | // 8 | // Interface: 9 | // * To get a buffer for a particular disk block, call bread. 10 | // * After changing buffer data, call bwrite to write it to disk. 11 | // * When done with the buffer, call brelse. 12 | // * Do not use the buffer after calling brelse. 13 | // * Only one process at a time can use a buffer, 14 | // so do not keep them longer than necessary. 15 | // 16 | // The implementation uses three state flags internally: 17 | // * B_BUSY: the block has been returned from bread 18 | // and has not been passed back to brelse. 19 | // * B_VALID: the buffer data has been read from the disk. 20 | // * B_DIRTY: the buffer data has been modified 21 | // and needs to be written to disk. 22 | 23 | #include "types.h" 24 | #include "defs.h" 25 | #include "param.h" 26 | #include "spinlock.h" 27 | #include "buf.h" 28 | 29 | struct { 30 | struct spinlock lock; 31 | struct buf buf[NBUF]; 32 | 33 | // Linked list of all buffers, through prev/next. 34 | // head.next is most recently used. 35 | struct buf head; 36 | } bcache; 37 | 38 | void 39 | binit(void) 40 | { 41 | struct buf *b; 42 | 43 | memset(&bcache, 0, sizeof(bcache)); 44 | initlock(&bcache.lock, "bcache"); 45 | 46 | //PAGEBREAK! 47 | // Create linked list of buffers 48 | bcache.head.prev = &bcache.head; 49 | bcache.head.next = &bcache.head; 50 | for(b = bcache.buf; b < bcache.buf+NBUF; b++){ 51 | b->next = bcache.head.next; 52 | b->prev = &bcache.head; 53 | b->dev = -1; 54 | bcache.head.next->prev = b; 55 | bcache.head.next = b; 56 | } 57 | } 58 | 59 | // Look through buffer cache for sector on device dev. 60 | // If not found, allocate fresh block. 61 | // In either case, return B_BUSY buffer. 62 | static struct buf* 63 | bget(uint dev, uint sector) 64 | { 65 | struct buf *b; 66 | 67 | acquire(&bcache.lock); 68 | 69 | loop: 70 | // Is the sector already cached? 71 | for(b = bcache.head.next; b != &bcache.head; b = b->next){ 72 | if(b->dev == dev && b->sector == sector){ 73 | if(!(b->flags & B_BUSY)){ 74 | b->flags |= B_BUSY; 75 | release(&bcache.lock); 76 | return b; 77 | } 78 | sleep(b, &bcache.lock); 79 | goto loop; 80 | } 81 | } 82 | 83 | // Not cached; recycle some non-busy and clean buffer. 84 | for(b = bcache.head.prev; b != &bcache.head; b = b->prev){ 85 | if((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0){ 86 | b->dev = dev; 87 | b->sector = sector; 88 | b->flags = B_BUSY; 89 | release(&bcache.lock); 90 | return b; 91 | } 92 | } 93 | panic("bget: no buffers"); 94 | return 0; 95 | } 96 | 97 | // Return a B_BUSY buf with the contents of the indicated disk sector. 98 | struct buf* 99 | bread(uint dev, uint sector) 100 | { 101 | struct buf *b; 102 | 103 | b = bget(dev, sector); 104 | if(!(b->flags & B_VALID)) 105 | iderw(b); 106 | return b; 107 | } 108 | 109 | // Write b's contents to disk. Must be B_BUSY. 110 | void 111 | bwrite(struct buf *b) 112 | { 113 | if((b->flags & B_BUSY) == 0) 114 | panic("bwrite"); 115 | b->flags |= B_DIRTY; 116 | iderw(b); 117 | } 118 | 119 | // Release a B_BUSY buffer. 120 | // Move to the head of the MRU list. 121 | void 122 | brelse(struct buf *b) 123 | { 124 | if((b->flags & B_BUSY) == 0) 125 | panic("brelse"); 126 | 127 | acquire(&bcache.lock); 128 | 129 | b->next->prev = b->prev; 130 | b->prev->next = b->next; 131 | b->next = bcache.head.next; 132 | b->prev = &bcache.head; 133 | bcache.head.next->prev = b; 134 | bcache.head.next = b; 135 | 136 | b->flags &= ~B_BUSY; 137 | wakeup(b); 138 | 139 | release(&bcache.lock); 140 | } 141 | 142 | -------------------------------------------------------------------------------- /source/exec.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "param.h" 3 | #include "memlayout.h" 4 | #include "mmu.h" 5 | #include "proc.h" 6 | #include "defs.h" 7 | #include "arm.h" 8 | #include "elf.h" 9 | 10 | int 11 | exec(char *path, char **argv) 12 | { 13 | char *last; 14 | int i, off; 15 | uint argc, sz, sp, ustack[3+MAXARG+1]; 16 | struct elfhdr elf; 17 | struct inode *ip; 18 | struct proghdr ph; 19 | pde_t *pgdir, *oldpgdir; 20 | u32 old_sz = 0; 21 | if((ip = namei(path)) == 0) 22 | return -1; 23 | ilock(ip); 24 | pgdir = 0; 25 | 26 | // Check ELF header 27 | if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf)) 28 | goto bad; 29 | if(elf.magic != ELF_MAGIC) 30 | goto bad; 31 | 32 | if((pgdir = setupkvm()) == 0) 33 | goto bad; 34 | // Load program into memory. 35 | sz = 0; 36 | for(i=0, off=elf.phoff; i= MAXARG) 61 | goto bad; 62 | sp = (sp - (strlen(argv[argc]) + 1)) & ~3; 63 | if(copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0) 64 | goto bad; 65 | ustack[3+argc] = sp; 66 | } 67 | ustack[3+argc] = 0; 68 | 69 | //cprintf("Exec is called argc=%d sz=%x\n", argc, sz); 70 | 71 | ustack[0] = 0xffffffff; // fake return PC 72 | ustack[1] = argc; 73 | ustack[2] = sp - (argc+1)*4; // argv pointer 74 | 75 | sp -= (3+argc+1) * 4; 76 | if(copyout(pgdir, sp, ustack, (3+argc+1)*4) < 0) 77 | goto bad; 78 | 79 | // Save program name for debugging. 80 | /* for(last=s=path; *s; s++) 81 | if(*s == '/') 82 | last = s+1;*/ 83 | last = argv[0]; 84 | safestrcpy(curr_proc->name, last, sizeof(curr_proc->name)); 85 | 86 | // Commit to the user image. 87 | oldpgdir = curr_proc->pgdir; 88 | if (curr_proc) { 89 | old_sz = curr_proc->sz; 90 | } 91 | curr_proc->pgdir = pgdir; 92 | curr_proc->sz = sz; 93 | curr_proc->tf->pc = elf.entry; // main 94 | curr_proc->tf->sp = sp; 95 | curr_proc->tf->r0 = ustack[1]; 96 | curr_proc->tf->r1 = ustack[2]; 97 | switchuvm(curr_proc, old_sz); 98 | freevm(oldpgdir); 99 | return 0; 100 | 101 | bad: 102 | if(pgdir) 103 | freevm(pgdir); 104 | if(ip) 105 | iunlockput(ip); 106 | return -1; 107 | } 108 | -------------------------------------------------------------------------------- /source/file.c: -------------------------------------------------------------------------------- 1 | // 2 | // File descriptors 3 | // 4 | 5 | #include "types.h" 6 | #include "defs.h" 7 | #include "param.h" 8 | #include "fs.h" 9 | #include "file.h" 10 | #include "spinlock.h" 11 | 12 | struct devsw devsw[NDEV]; 13 | struct { 14 | struct spinlock lock; 15 | struct file file[NFILE]; 16 | } ftable; 17 | 18 | void 19 | fileinit(void) 20 | { 21 | memset(&ftable, 0, sizeof(ftable)); 22 | initlock(&ftable.lock, "ftable"); 23 | } 24 | 25 | // Allocate a file structure. 26 | struct file* 27 | filealloc(void) 28 | { 29 | struct file *f; 30 | 31 | acquire(&ftable.lock); 32 | for(f = ftable.file; f < ftable.file + NFILE; f++){ 33 | if(f->ref == 0){ 34 | f->ref = 1; 35 | release(&ftable.lock); 36 | return f; 37 | } 38 | } 39 | release(&ftable.lock); 40 | return 0; 41 | } 42 | 43 | // Increment ref count for file f. 44 | struct file* 45 | filedup(struct file *f) 46 | { 47 | acquire(&ftable.lock); 48 | if(f->ref < 1) 49 | panic("filedup"); 50 | f->ref++; 51 | release(&ftable.lock); 52 | return f; 53 | } 54 | 55 | // Close file f. (Decrement ref count, close when reaches 0.) 56 | void 57 | fileclose(struct file *f) 58 | { 59 | struct file ff; 60 | 61 | acquire(&ftable.lock); 62 | if(f->ref < 1) 63 | panic("fileclose"); 64 | if(--f->ref > 0){ 65 | release(&ftable.lock); 66 | return; 67 | } 68 | ff = *f; 69 | f->ref = 0; 70 | f->type = FD_NONE; 71 | release(&ftable.lock); 72 | 73 | if(ff.type == FD_PIPE) 74 | pipeclose(ff.pipe, ff.writable); 75 | else if(ff.type == FD_INODE){ 76 | begin_trans(); 77 | iput(ff.ip); 78 | commit_trans(); 79 | } 80 | } 81 | 82 | // Get metadata about file f. 83 | int 84 | filestat(struct file *f, struct stat *st) 85 | { 86 | if(f->type == FD_INODE){ 87 | ilock(f->ip); 88 | stati(f->ip, st); 89 | iunlock(f->ip); 90 | return 0; 91 | } 92 | return -1; 93 | } 94 | 95 | // Read from file f. 96 | int 97 | fileread(struct file *f, char *addr, int n) 98 | { 99 | int r; 100 | 101 | if(f->readable == 0) 102 | return -1; 103 | if(f->type == FD_PIPE) 104 | return piperead(f->pipe, addr, n); 105 | if(f->type == FD_INODE){ 106 | ilock(f->ip); 107 | //cprintf("inside fileread\n"); 108 | if((r = readi(f->ip, addr, f->off, n)) > 0) 109 | f->off += r; 110 | //cprintf("inside fileread: after readi rv=%x\n", r); 111 | iunlock(f->ip); 112 | return r; 113 | } 114 | panic("fileread"); 115 | return -1; 116 | } 117 | 118 | //PAGEBREAK! 119 | // Write to file f. 120 | int 121 | filewrite(struct file *f, char *addr, int n) 122 | { 123 | int r; 124 | 125 | if(f->writable == 0) 126 | return -1; 127 | //cprintf("inside filewrite\n"); 128 | if(f->type == FD_PIPE) 129 | return pipewrite(f->pipe, addr, n); 130 | if(f->type == FD_INODE){ 131 | // write a few blocks at a time to avoid exceeding 132 | // the maximum log transaction size, including 133 | // i-node, indirect block, allocation blocks, 134 | // and 2 blocks of slop for non-aligned writes. 135 | // this really belongs lower down, since writei() 136 | // might be writing a device like the console. 137 | int max = ((LOGSIZE-1-1-2) / 2) * 512; 138 | int i = 0; 139 | while(i < n){ 140 | int n1 = n - i; 141 | if(n1 > max) 142 | n1 = max; 143 | 144 | begin_trans(); 145 | ilock(f->ip); 146 | if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) 147 | f->off += r; 148 | iunlock(f->ip); 149 | commit_trans(); 150 | 151 | if(r < 0) 152 | break; 153 | if(r != n1) 154 | panic("short filewrite"); 155 | i += r; 156 | } 157 | return i == n ? n : -1; 158 | } 159 | panic("filewrite"); 160 | return -1; 161 | } 162 | 163 | -------------------------------------------------------------------------------- /source/font.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/source/font.bin -------------------------------------------------------------------------------- /source/font1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/source/font1.bin -------------------------------------------------------------------------------- /source/fs.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/source/fs.img -------------------------------------------------------------------------------- /source/initcode: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/source/initcode -------------------------------------------------------------------------------- /source/initcode.S: -------------------------------------------------------------------------------- 1 | # Initial process execs /init. 2 | 3 | #include "syscall.h" 4 | #include "traps.h" 5 | 6 | 7 | # exec(init, argv) 8 | .globl start 9 | start: 10 | push {lr} 11 | ldr r0, =argv 12 | push {r0} 13 | ldr r0, =init 14 | push {r0} 15 | mov r0, #SYS_exec 16 | swi #T_SYSCALL 17 | pop {lr} 18 | pop {lr} 19 | pop {lr} 20 | bx lr 21 | 22 | # for(;;) exit(); 23 | exit: 24 | mov r11, #SYS_exit 25 | swi #T_SYSCALL 26 | bl exit 27 | 28 | # char init[] = "/init\0"; 29 | init: 30 | .string "/init\0" 31 | 32 | # char *argv[] = { init, 0 }; 33 | .p2align 2 34 | argv: 35 | .long init 36 | .long 0 37 | 38 | -------------------------------------------------------------------------------- /source/kalloc.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "defs.h" 3 | #include "param.h" 4 | #include "memlayout.h" 5 | #include "mmu.h" 6 | #include "spinlock.h" 7 | 8 | void freerange(void *vstart, void *vend); 9 | extern char end[]; // first address after kernel loaded from ELF file 10 | extern unsigned int pm_size; 11 | 12 | struct run { 13 | struct run *next; 14 | }; 15 | 16 | struct { 17 | struct spinlock lock; 18 | int use_lock; 19 | struct run *freelist; 20 | } kmem; 21 | 22 | // Initialization happens in two phases. 23 | // 1. main() calls kinit1() while still using entrypgdir to place just 24 | // the pages mapped by entrypgdir on free list. 25 | // 2. main() calls kinit2() with the rest of the physical pages 26 | // after installing a full page table that maps them on all cores. 27 | void 28 | kinit1(void *vstart, void *vend) 29 | { 30 | pm_size = 0x400*0x400*32; // assume at least 32 MB physical memory 31 | initlock(&kmem.lock, "kmem"); 32 | kmem.use_lock = 0; 33 | kmem.freelist = 0; 34 | freerange(vstart, vend); 35 | } 36 | 37 | void 38 | kinit2(void *vstart, void *vend) 39 | { 40 | freerange(vstart, vend); 41 | kmem.use_lock = 1; 42 | } 43 | 44 | void 45 | freerange(void *vstart, void *vend) 46 | { 47 | char *p; 48 | p = (char*)PGROUNDUP((uint)vstart); 49 | for(; p + PGSIZE <= (char*)vend; p += PGSIZE) { 50 | kfree(p); 51 | } 52 | } 53 | 54 | //PAGEBREAK: 21 55 | // Free the page of physical memory pointed at by v, 56 | // which normally should have been returned by a 57 | // call to kalloc(). (The exception is when 58 | // initializing the allocator; see kinit above.) 59 | void 60 | kfree(char *v) 61 | { 62 | struct run *r; 63 | if((uint)v % PGSIZE || v < end || v2p(v) >= pm_size) { 64 | panic("kfree"); 65 | } 66 | // Fill with junk to catch dangling refs. 67 | memset(v, 0xff, PGSIZE); //commented out to speed up 68 | 69 | if(kmem.use_lock){ 70 | acquire(&kmem.lock); 71 | } 72 | r = (struct run*)v; 73 | r->next = kmem.freelist; 74 | kmem.freelist = r; 75 | if(kmem.use_lock) { 76 | release(&kmem.lock); 77 | } 78 | } 79 | 80 | // Allocate one 4096-byte page of physical memory. 81 | // Returns a pointer that the kernel can use. 82 | // Returns 0 if the memory cannot be allocated. 83 | char* 84 | kalloc(void) 85 | { 86 | struct run *r; 87 | 88 | if(kmem.use_lock) 89 | acquire(&kmem.lock); 90 | r = kmem.freelist; 91 | if(r) 92 | kmem.freelist = r->next; 93 | if(kmem.use_lock) 94 | release(&kmem.lock); 95 | return (char*)r; 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /source/mailbox.c: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * mailbox.c 3 | * by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | 10 | #include "types.h" 11 | #include "defs.h" 12 | #include "param.h" 13 | #include "traps.h" 14 | #include "spinlock.h" 15 | #include "fs.h" 16 | #include "file.h" 17 | #include "memlayout.h" 18 | #include "mmu.h" 19 | #include "proc.h" 20 | #include "arm.h" 21 | #include "mailbox.h" 22 | 23 | /* Note: for more tags refer to 24 | https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */ 25 | 26 | 27 | void 28 | create_request(volatile uint *mbuf, uint tag, uint buflen, uint len, uint *data) 29 | { 30 | int i; 31 | volatile uint *tag_info; 32 | uint nw, tag_len, total_len; 33 | 34 | tag_info = mbuf + POS_TAG; 35 | 36 | tag_info[POS_TAG_ID] = tag; 37 | tag_info[POS_TAG_BUFLEN] = buflen; 38 | tag_info[POS_TAG_DATALEN] = len & 0x7FFFFFFF; 39 | 40 | nw = buflen >> 2; 41 | 42 | if (!data) 43 | for (i = 0; i < nw; ++i) tag_info[POS_TAG_DATA + i] = 0; 44 | else 45 | for (i = 0; i < nw; ++i) tag_info[POS_TAG_DATA + i] = data[i]; 46 | 47 | tag_info[POS_TAG_DATA+nw] = 0; // indicate end of tag 48 | 49 | tag_len = mbuf[MB_HEADER_LENGTH + POS_TAG_BUFLEN]; 50 | total_len = (MB_HEADER_LENGTH*4) + (TAG_HEADER_LENGTH*4) + tag_len + 4; 51 | 52 | mbuf[POS_OVERALL_LENGTH] = total_len; 53 | mbuf[POS_RV] = MPI_REQUEST; 54 | 55 | } 56 | 57 | volatile uint *mailbuffer; 58 | 59 | void mailboxinit() 60 | { 61 | mailbuffer = (uint *)kalloc(); 62 | #ifdef RPI1 63 | flush_dcache_all(); 64 | #else 65 | invalidate_dcache_range((void*) mailbuffer, PGSIZE); 66 | #endif 67 | } 68 | 69 | uint 70 | readmailbox(u8 channel) 71 | { 72 | uint x, y, z; 73 | 74 | again: 75 | while ((inw(MAILBOX_BASE+24) & 0x40000000) != 0); 76 | x = inw(MAILBOX_BASE); 77 | z = x & 0xf; y = (uint)(channel & 0xf); 78 | if(z != y) goto again; 79 | #ifdef RPI1 80 | flush_dcache_all(); 81 | #else 82 | invalidate_dcache_range((void*) mailbuffer, PGSIZE); 83 | #endif 84 | return x&0xfffffff0; 85 | } 86 | 87 | void 88 | writemailbox(uint *addr, u8 channel) 89 | { 90 | uint x, y, a; 91 | 92 | a = (uint)addr; 93 | a -= KERNBASE; /* convert to ARM physical address */ 94 | a += 0xc0000000; /* convert to VC address space */ 95 | x = a & 0xfffffff0; 96 | y = x | (uint)(channel & 0xf); 97 | 98 | #ifdef RPI1 99 | flush_dcache_all(); 100 | #else 101 | flush_dcache_range((void*) addr, PGSIZE); 102 | #endif 103 | while ((inw(MAILBOX_BASE+24) & 0x80000000) != 0); 104 | outw(MAILBOX_BASE+32, y); 105 | } 106 | -------------------------------------------------------------------------------- /source/memide.c: -------------------------------------------------------------------------------- 1 | // Fake IDE disk; stores blocks in memory. 2 | // Useful for running kernel without scratch disk. 3 | 4 | #include "types.h" 5 | #include "defs.h" 6 | #include "param.h" 7 | #include "mmu.h" 8 | #include "proc.h" 9 | #include "arm.h" 10 | #include "traps.h" 11 | #include "spinlock.h" 12 | #include "buf.h" 13 | 14 | extern uchar _binary_fs_img_start[], _binary_fs_img_end[]; 15 | 16 | static int disksize; 17 | static uchar *memdisk; 18 | 19 | void 20 | ideinit(void) 21 | { 22 | memdisk = _binary_fs_img_start; 23 | disksize = div(((uint)_binary_fs_img_end - (uint)_binary_fs_img_start), 512); 24 | } 25 | 26 | // Interrupt handler. 27 | void 28 | ideintr(void) 29 | { 30 | // no-op 31 | } 32 | 33 | // Sync buf with disk. 34 | // If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID. 35 | // Else if B_VALID is not set, read buf from disk, set B_VALID. 36 | void 37 | iderw(struct buf *b) 38 | { 39 | uchar *p; 40 | 41 | if(!(b->flags & B_BUSY)) 42 | panic("iderw: buf not busy"); 43 | if((b->flags & (B_VALID|B_DIRTY)) == B_VALID) 44 | panic("iderw: nothing to do"); 45 | if(b->dev != 1) 46 | panic("iderw: request not for disk 1"); 47 | if(b->sector >= disksize) 48 | panic("iderw: sector out of range"); 49 | 50 | p = memdisk + b->sector*512; 51 | 52 | if(b->flags & B_DIRTY){ 53 | b->flags &= ~B_DIRTY; 54 | memmove(p, b->data, 512); 55 | } else 56 | memmove(b->data, p, 512); 57 | b->flags |= B_VALID; 58 | } 59 | -------------------------------------------------------------------------------- /source/pipe.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "defs.h" 3 | #include "param.h" 4 | #include "mmu.h" 5 | #include "proc.h" 6 | #include "fs.h" 7 | #include "file.h" 8 | #include "spinlock.h" 9 | 10 | #define PIPESIZE 512 11 | 12 | struct pipe { 13 | struct spinlock lock; 14 | char data[PIPESIZE]; 15 | uint nread; // number of bytes read 16 | uint nwrite; // number of bytes written 17 | int readopen; // read fd is still open 18 | int writeopen; // write fd is still open 19 | }; 20 | 21 | int 22 | pipealloc(struct file **f0, struct file **f1) 23 | { 24 | struct pipe *p; 25 | 26 | p = 0; 27 | *f0 = *f1 = 0; 28 | if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) 29 | goto bad; 30 | if((p = (struct pipe*)kalloc()) == 0) 31 | goto bad; 32 | memset(p, 0, PGSIZE); 33 | p->readopen = 1; 34 | p->writeopen = 1; 35 | p->nwrite = 0; 36 | p->nread = 0; 37 | initlock(&p->lock, "pipe"); 38 | (*f0)->type = FD_PIPE; 39 | (*f0)->readable = 1; 40 | (*f0)->writable = 0; 41 | (*f0)->pipe = p; 42 | (*f1)->type = FD_PIPE; 43 | (*f1)->readable = 0; 44 | (*f1)->writable = 1; 45 | (*f1)->pipe = p; 46 | return 0; 47 | 48 | //PAGEBREAK: 20 49 | bad: 50 | if(p) 51 | kfree((char*)p); 52 | if(*f0) 53 | fileclose(*f0); 54 | if(*f1) 55 | fileclose(*f1); 56 | return -1; 57 | } 58 | 59 | void 60 | pipeclose(struct pipe *p, int writable) 61 | { 62 | acquire(&p->lock); 63 | if(writable){ 64 | p->writeopen = 0; 65 | wakeup(&p->nread); 66 | } else { 67 | p->readopen = 0; 68 | wakeup(&p->nwrite); 69 | } 70 | if(p->readopen == 0 && p->writeopen == 0){ 71 | release(&p->lock); 72 | kfree((char*)p); 73 | } else 74 | release(&p->lock); 75 | } 76 | 77 | //PAGEBREAK: 40 78 | int 79 | pipewrite(struct pipe *p, char *addr, int n) 80 | { 81 | int i; 82 | 83 | acquire(&p->lock); 84 | for(i = 0; i < n; i++){ 85 | while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full 86 | if(p->readopen == 0 || curr_proc->killed){ 87 | release(&p->lock); 88 | return -1; 89 | } 90 | wakeup(&p->nread); 91 | sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep 92 | } 93 | p->data[p->nwrite++ % PIPESIZE] = addr[i]; 94 | } 95 | wakeup(&p->nread); //DOC: pipewrite-wakeup1 96 | release(&p->lock); 97 | return n; 98 | } 99 | 100 | int 101 | piperead(struct pipe *p, char *addr, int n) 102 | { 103 | int i; 104 | 105 | acquire(&p->lock); 106 | while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty 107 | if(curr_proc->killed){ 108 | release(&p->lock); 109 | return -1; 110 | } 111 | sleep(&p->nread, &p->lock); //DOC: piperead-sleep 112 | } 113 | for(i = 0; i < n; i++){ //DOC: piperead-copy 114 | if(p->nread == p->nwrite) 115 | break; 116 | addr[i] = p->data[p->nread++ % PIPESIZE]; 117 | } 118 | wakeup(&p->nwrite); //DOC: piperead-wakeup 119 | release(&p->lock); 120 | return i; 121 | } 122 | -------------------------------------------------------------------------------- /source/spinlock.c: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * spinlock.c 3 | * adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | 10 | #include "types.h" 11 | #include "defs.h" 12 | #include "param.h" 13 | #include "arm.h" 14 | #include "memlayout.h" 15 | #include "mmu.h" 16 | #include "proc.h" 17 | #include "spinlock.h" 18 | 19 | extern void spin_acquire(void* lockvar); 20 | extern void spin_release(void* lockvar); 21 | 22 | 23 | void 24 | initlock(struct spinlock *lk, char *name) 25 | { 26 | lk->name = name; 27 | lk->locked = 0; 28 | lk->cpu = 0; 29 | } 30 | 31 | // Acquire the lock. 32 | // Loops (spins) until the lock is acquired. 33 | // Holding a lock for a long time may cause 34 | // other CPUs to waste time spinning to acquire it. 35 | void 36 | acquire(struct spinlock *lk) 37 | { 38 | pushcli(); // disable interrupts to avoid deadlock. 39 | if(holding(lk)){ 40 | cprintf("lock name: %s, locked: %d, cpu: %x CPSR: %x\n", lk->name, lk->locked, lk->cpu, readcpsr()); 41 | panic("acquire"); 42 | } 43 | spin_acquire((void*) &lk->locked); 44 | // Record info about lock acquisition for debugging. 45 | lk->cpu = curr_cpu; 46 | } 47 | 48 | // Release the lock. 49 | void 50 | release(struct spinlock *lk) 51 | { 52 | 53 | if(!holding(lk)) 54 | panic("release"); 55 | 56 | lk->pcs[0] = 0; 57 | lk->cpu = 0; 58 | spin_release((void*) &lk->locked); 59 | popcli(); 60 | } 61 | 62 | // Record the current call stack in pcs[] by following the %ebp chain. 63 | void 64 | getcallerpcs(void *v, uint pcs[]) 65 | { 66 | } 67 | 68 | 69 | // Check whether this cpu is holding the lock. 70 | int 71 | holding(struct spinlock *lock) 72 | { 73 | int rv; 74 | rv = lock->locked && lock->cpu == curr_cpu; 75 | /* if(rv){ 76 | cprintf("The held lock: %s, locked: %d, cpu: %x\n", lock->name, lock->locked, lock->cpu); 77 | }*/ 78 | return rv; 79 | } 80 | 81 | 82 | // Pushcli/popcli are like cli/sti except that they are matched: 83 | // it takes two popcli to undo two pushcli. Also, if interrupts 84 | // are off, then pushcli, popcli leaves them off. 85 | 86 | void 87 | pushcli(void) 88 | { 89 | uint cpsr; 90 | cpsr = readcpsr(); 91 | cli(); 92 | if(curr_cpu->ncli++ == 0) 93 | curr_cpu->intena = (cpsr & PSR_DISABLE_IRQ) ? 0: 1; 94 | } 95 | 96 | void 97 | popcli(void) 98 | { 99 | if(!(readcpsr()&PSR_DISABLE_IRQ)) 100 | panic("popcli - interruptible"); 101 | if(--curr_cpu->ncli < 0) 102 | panic("popcli"); 103 | if(curr_cpu->ncli == 0 && curr_cpu->intena) 104 | sti(); 105 | } 106 | 107 | -------------------------------------------------------------------------------- /source/string.c: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * string.c 3 | * adapted from MIT xv6 by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | 9 | #include "types.h" 10 | 11 | void* 12 | memsetw(int *dst, int c, uint n) 13 | { 14 | int *p=dst; 15 | uint rc=n; 16 | 17 | while (rc-- > 0) *p++ = c; 18 | return (void *)p; 19 | } 20 | 21 | void* 22 | memsetb(char *dst, int c, uint n) 23 | { 24 | char *p=dst; 25 | uint rc=n; 26 | 27 | while (rc-- > 0) *p++ = c; 28 | return (void *)p; 29 | } 30 | 31 | 32 | void* 33 | memset(void *dst, int c, uint n) 34 | { 35 | if ((int)dst%4 == 0 && n%4 == 0){ 36 | c &= 0xFF; 37 | return memsetw((int *)dst, (c<<24)|(c<<16)|(c<<8)|c, n/4); 38 | } else 39 | return memsetb((char *)dst, c, n); 40 | } 41 | 42 | int 43 | memcmp(const void *v1, const void *v2, uint n) 44 | { 45 | const u8 *s1, *s2; 46 | 47 | s1 = v1; 48 | s2 = v2; 49 | while(n-- > 0){ 50 | if(*s1 != *s2) 51 | return *s1 - *s2; 52 | s1++, s2++; 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | void* 59 | memmove(void *dst, const void *src, uint n) 60 | { 61 | const char *s; 62 | char *d; 63 | 64 | s = src; 65 | d = dst; 66 | if(s < d && s + n > d){ 67 | s += n; 68 | d += n; 69 | while(n-- > 0) 70 | *--d = *--s; 71 | } else 72 | while(n-- > 0) 73 | *d++ = *s++; 74 | 75 | return dst; 76 | } 77 | 78 | // memcpy exists to placate GCC. Use memmove. 79 | void* 80 | memcpy(void *dst, const void *src, uint n) 81 | { 82 | return memmove(dst, src, n); 83 | } 84 | 85 | int 86 | strncmp(const char *p, const char *q, uint n) 87 | { 88 | while(n > 0 && *p && *p == *q) 89 | n--, p++, q++; 90 | if(n == 0) 91 | return 0; 92 | return (u8)*p - (u8)*q; 93 | } 94 | 95 | char* 96 | strncpy(char *s, const char *t, int n) 97 | { 98 | char *os; 99 | 100 | os = s; 101 | while(n-- > 0 && (*s++ = *t++) != 0) 102 | ; 103 | while(n-- > 0) 104 | *s++ = 0; 105 | return os; 106 | } 107 | 108 | // Like strncpy but guaranteed to NUL-terminate. 109 | char* 110 | safestrcpy(char *s, const char *t, int n) 111 | { 112 | char *os; 113 | 114 | os = s; 115 | if(n <= 0) 116 | return os; 117 | while(--n > 0 && (*s++ = *t++) != 0) 118 | ; 119 | *s = 0; 120 | return os; 121 | } 122 | 123 | int 124 | strlen(const char *s) 125 | { 126 | int n; 127 | 128 | for(n = 0; s[n]; n++) 129 | ; 130 | return n; 131 | } 132 | 133 | uint div(uint n, uint d) // long division 134 | { 135 | uint q=0, r=0; 136 | int i; 137 | 138 | for(i=31;i>=0;i--){ 139 | r = r << 1; 140 | r = r | ((n >> i) & 1); 141 | if(r >= d) { 142 | r = r - d; 143 | q = q | (1 << i); 144 | } 145 | } 146 | return q; 147 | } 148 | 149 | -------------------------------------------------------------------------------- /source/sysproc.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "arm.h" 3 | #include "defs.h" 4 | #include "param.h" 5 | #include "memlayout.h" 6 | #include "mmu.h" 7 | #include "proc.h" 8 | 9 | int 10 | sys_fork(void) 11 | { 12 | return fork(); 13 | } 14 | 15 | int 16 | sys_exit(void) 17 | { 18 | exit(); 19 | return 0; // not reached 20 | } 21 | 22 | int 23 | sys_wait(void) 24 | { 25 | return wait(); 26 | } 27 | 28 | int 29 | sys_kill(void) 30 | { 31 | int pid; 32 | 33 | if(argint(0, &pid) < 0) 34 | return -1; 35 | return kill(pid); 36 | } 37 | 38 | int 39 | sys_getpid(void) 40 | { 41 | return curr_proc->pid; 42 | } 43 | 44 | int 45 | sys_sbrk(void) 46 | { 47 | int addr; 48 | int n; 49 | 50 | if(argint(0, &n) < 0) 51 | return -1; 52 | addr = curr_proc->sz; 53 | if(growproc(n) < 0) 54 | return -1; 55 | return addr; 56 | } 57 | 58 | int 59 | sys_sleep(void) 60 | { 61 | int n; 62 | uint ticks0; 63 | 64 | if(argint(0, &n) < 0) 65 | return -1; 66 | acquire(&tickslock); 67 | ticks0 = ticks; 68 | while(ticks - ticks0 < n){ 69 | if(curr_proc->killed){ 70 | release(&tickslock); 71 | return -1; 72 | } 73 | sleep(&ticks, &tickslock); 74 | } 75 | release(&tickslock); 76 | return 0; 77 | } 78 | 79 | // return how many clock tick interrupts have occurred 80 | // since start. 81 | int 82 | sys_uptime(void) 83 | { 84 | uint xticks; 85 | 86 | acquire(&tickslock); 87 | xticks = ticks; 88 | release(&tickslock); 89 | return xticks; 90 | } 91 | -------------------------------------------------------------------------------- /source/timer.c: -------------------------------------------------------------------------------- 1 | /***************************************************************** 2 | * timer.c 3 | * by Zhiyi Huang, hzy@cs.otago.ac.nz 4 | * University of Otago 5 | * 6 | ********************************************************************/ 7 | 8 | // The System Timer peripheral 9 | 10 | #include "types.h" 11 | #include "defs.h" 12 | #include "param.h" 13 | #include "memlayout.h" 14 | #include "proc.h" 15 | #include "traps.h" 16 | #include "arm.h" 17 | #include "spinlock.h" 18 | 19 | #define TIMER_REGS_BASE (MMIO_VA+0x003000) 20 | #define CONTROL_STATUS 0x0 // control/status 21 | #define COUNTER_LO 0x4 // the time-stamp lower 32 bits 22 | #define COUNTER_HI 0x8 // the time-stamp higher 32 bits 23 | #define COMPARE0 0xc // compare 0 24 | #define COMPARE1 0x10 // compare 1 25 | #define COMPARE2 0x14 // compare 2 26 | #define COMPARE3 0x18 // compare 3 27 | 28 | #define TIMER_FREQ 50000 // interrupt 20 times/sec. 29 | 30 | void led_on(); 31 | void led_off(); 32 | 33 | void enabletimer3irq(void) 34 | { 35 | intctrlregs *ip; 36 | 37 | ip = (intctrlregs *)INT_REGS_BASE; 38 | ip->gpuenable[0] |= 1 << IRQ_TIMER3; // enable the system timer3 irq 39 | } 40 | 41 | 42 | void 43 | timer3init(void) 44 | { 45 | uint v; 46 | 47 | enabletimer3irq(); 48 | 49 | v = inw(TIMER_REGS_BASE+COUNTER_LO); 50 | v += TIMER_FREQ; 51 | 52 | outw(TIMER_REGS_BASE+COMPARE3, v); 53 | ticks = 0; 54 | } 55 | 56 | void 57 | timer3intr(void) 58 | { 59 | uint v; 60 | //cprintf("timer3 interrupt: %x\n", inw(TIMER_REGS_BASE+CONTROL_STATUS)); 61 | outw(TIMER_REGS_BASE+CONTROL_STATUS, (1 << IRQ_TIMER3)); // clear timer3 irq 62 | 63 | ticks++; 64 | wakeup(&ticks); 65 | 66 | // reset the value of compare3 67 | v=inw(TIMER_REGS_BASE+COUNTER_LO); 68 | v += TIMER_FREQ; 69 | outw(TIMER_REGS_BASE+COMPARE3, v); 70 | } 71 | 72 | void 73 | delay(uint m) 74 | { 75 | unsigned long long t; 76 | 77 | if(m == 0) return; 78 | 79 | t = getsystemtime() + m; 80 | //led_on(); 81 | while(t != getsystemtime()); 82 | //led_off(); 83 | 84 | return; 85 | } 86 | 87 | void led_on() 88 | { 89 | setgpiofunc(18, 1); // gpio 18 for Ok Led, set as an output 90 | setgpioval(18, 1); 91 | } 92 | 93 | void led_off() 94 | { 95 | setgpiofunc(18, 1); // gpio 18 for Ok Led, set as an output 96 | setgpioval(18, 0); 97 | } 98 | 99 | /** 100 | * sys_time returns the system clock time to user space, 101 | * via a system call. 102 | * 103 | * sys_time can only return 32 bits on a syscall interface, 104 | * so only the lower 32 bits are returned. 105 | * 106 | * There should be 1,000,000 ticks per second on the system 107 | * clock. 108 | * 109 | * Therefore, the value of sys_time should rollover aproximatly 110 | * every 71 mintues. 111 | */ 112 | int sys_time(void) 113 | { 114 | return getsystemtime(); 115 | } 116 | -------------------------------------------------------------------------------- /source/uart_pl011.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pl011.c 3 | * 4 | * Created on: Nov 20, 2016 5 | * Author: Mahdi Amiri 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | uint uart_lock; //Mutex lock 12 | 13 | void uartinit_fvp(){ 14 | /* Enable pl011 interrupts */ 15 | *(volatile uint*) FVP_PL011_UARTIMSC = FVP_PL011_UARTIMSC_RXIM; 16 | 17 | /* Enable pl011 controller */ 18 | *(volatile uint*) FVP_PL011_UARTCR = 19 | *(volatile uint*) FVP_PL011_UARTCR | FVP_PL011_UARTCR_UARTEN | FVP_PL011_UARTCR_TXE | FVP_PL011_UARTCR_RXE; 20 | //outw(UARTCR,inw(UARTCR) | UARTCR_UARTEN | UARTCR_TXE | UARTCR_RXE); 21 | //enable_irq(37,1); 22 | uart_lock=0; // Open Mutex lock 23 | } 24 | 25 | void uartputc_fvp(uint c) 26 | { 27 | if(c=='\n') { 28 | /* Wait until the buffer is empty */ 29 | while (*(volatile uint*)(FVP_PL011_UARTFR) & (FVP_PL011_UARTFR_TXFF)); 30 | //while (inw(UARTFR) & UARTFR_TXFF); 31 | /* Put the character into the register */ 32 | *(volatile uint*) FVP_PL011_UARTDR = 0x0d; 33 | //outw(UARTDR , c); 34 | } 35 | while (*(volatile uint*)(FVP_PL011_UARTFR) & (FVP_PL011_UARTFR_TXFF)); 36 | *(volatile uint*) FVP_PL011_UARTDR = c; 37 | 38 | 39 | } 40 | 41 | uint uartgetc_fvp() 42 | { 43 | /* Wait until the buffer is empty */ 44 | while (*(volatile uint*)(FVP_PL011_UARTFR) & (FVP_PL011_UARTFR_RXFE)); 45 | //while (inw(UARTFR) & UARTFR_RXFE); 46 | /* Put the character into the register */ 47 | return *(volatile uint*) FVP_PL011_UARTDR; 48 | //outw(UARTDR , c); 49 | } 50 | -------------------------------------------------------------------------------- /source/uspi_devicenameservice.c: -------------------------------------------------------------------------------- 1 | // 2 | // devicenameservice.c 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | static TDeviceNameService *s_pThis = 0; 26 | 27 | void DeviceNameService (TDeviceNameService *pThis) 28 | { 29 | assert (pThis != 0); 30 | 31 | pThis->m_pList = 0; 32 | 33 | assert (s_pThis == 0); 34 | s_pThis = pThis; 35 | } 36 | 37 | void _DeviceNameService (TDeviceNameService *pThis) 38 | { 39 | assert (pThis != 0); 40 | 41 | while (pThis->m_pList != 0) 42 | { 43 | TDeviceInfo *pNext = pThis->m_pList->pNext; 44 | 45 | assert (pThis->m_pList->pName != 0); 46 | free (pThis->m_pList->pName); 47 | pThis->m_pList->pName = 0; 48 | 49 | pThis->m_pList->pDevice = 0; 50 | 51 | free (pThis->m_pList); 52 | 53 | pThis->m_pList = pNext; 54 | } 55 | 56 | s_pThis = 0; 57 | } 58 | 59 | void DeviceNameServiceAddDevice (TDeviceNameService *pThis, const char *pName, void *pDevice, boolean bBlockDevice) 60 | { 61 | assert (pThis != 0); 62 | 63 | TDeviceInfo *pInfo = (TDeviceInfo *) malloc (sizeof (TDeviceInfo)); 64 | assert (pInfo != 0); 65 | 66 | assert (pName != 0); 67 | pInfo->pName = (char *) malloc (strlen (pName)+1); 68 | assert (pInfo->pName != 0); 69 | strcpy (pInfo->pName, pName); 70 | 71 | assert (pDevice != 0); 72 | pInfo->pDevice = pDevice; 73 | 74 | pInfo->bBlockDevice = bBlockDevice; 75 | 76 | pInfo->pNext = pThis->m_pList; 77 | pThis->m_pList = pInfo; 78 | } 79 | 80 | void *DeviceNameServiceGetDevice (TDeviceNameService *pThis, const char *pName, boolean bBlockDevice) 81 | { 82 | assert (pThis != 0); 83 | assert (pName != 0); 84 | 85 | TDeviceInfo *pInfo = pThis->m_pList; 86 | while (pInfo != 0) 87 | { 88 | assert (pInfo->pName != 0); 89 | if ( strcmp (pName, pInfo->pName) == 0 90 | && pInfo->bBlockDevice == bBlockDevice) 91 | { 92 | assert (pInfo->pDevice != 0); 93 | return pInfo->pDevice; 94 | } 95 | 96 | pInfo = pInfo->pNext; 97 | } 98 | 99 | return 0; 100 | } 101 | 102 | TDeviceNameService *DeviceNameServiceGet (void) 103 | { 104 | assert (s_pThis != 0); 105 | return s_pThis; 106 | } 107 | -------------------------------------------------------------------------------- /source/uspi_dwhciframeschednsplit.c: -------------------------------------------------------------------------------- 1 | // 2 | // dwhciframeschednsplit.c 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | #include 22 | #include 23 | 24 | #define FRAME_UNSET (DWHCI_MAX_FRAME_NUMBER+1) 25 | 26 | void DWHCIFrameSchedulerNoSplit (TDWHCIFrameSchedulerNoSplit *pThis, boolean bIsPeriodic) 27 | { 28 | assert (pThis != 0); 29 | 30 | TDWHCIFrameScheduler *pBase = (TDWHCIFrameScheduler *) pThis; 31 | 32 | pBase->_DWHCIFrameScheduler = _DWHCIFrameSchedulerNoSplit; 33 | pBase->StartSplit = DWHCIFrameSchedulerNoSplitStartSplit; 34 | pBase->CompleteSplit = DWHCIFrameSchedulerNoSplitCompleteSplit; 35 | pBase->TransactionComplete = DWHCIFrameSchedulerNoSplitTransactionComplete; 36 | pBase->WaitForFrame = DWHCIFrameSchedulerNoSplitWaitForFrame; 37 | pBase->IsOddFrame = DWHCIFrameSchedulerNoSplitIsOddFrame; 38 | 39 | pThis->m_bIsPeriodic = bIsPeriodic; 40 | pThis->m_nNextFrame = FRAME_UNSET; 41 | 42 | } 43 | 44 | void _DWHCIFrameSchedulerNoSplit (TDWHCIFrameScheduler *pBase) 45 | { 46 | } 47 | 48 | void DWHCIFrameSchedulerNoSplitStartSplit (TDWHCIFrameScheduler *pBase) 49 | { 50 | assert (0); 51 | } 52 | 53 | boolean DWHCIFrameSchedulerNoSplitCompleteSplit (TDWHCIFrameScheduler *pBase) 54 | { 55 | assert (0); 56 | return FALSE; 57 | } 58 | 59 | void DWHCIFrameSchedulerNoSplitTransactionComplete (TDWHCIFrameScheduler *pBase, u32 nStatus) 60 | { 61 | assert (0); 62 | } 63 | 64 | void DWHCIFrameSchedulerNoSplitWaitForFrame (TDWHCIFrameScheduler *pBase) 65 | { 66 | TDWHCIFrameSchedulerNoSplit *pThis = (TDWHCIFrameSchedulerNoSplit *) pBase; 67 | assert (pThis != 0); 68 | 69 | TDWHCIRegister FrameNumber; 70 | DWHCIRegister (&FrameNumber, DWHCI_HOST_FRM_NUM); 71 | 72 | pThis->m_nNextFrame = (DWHCI_HOST_FRM_NUM_NUMBER (DWHCIRegisterRead (&FrameNumber))+1) & DWHCI_MAX_FRAME_NUMBER; 73 | 74 | if (!pThis->m_bIsPeriodic) 75 | { 76 | while ((DWHCI_HOST_FRM_NUM_NUMBER (DWHCIRegisterRead (&FrameNumber)) & DWHCI_MAX_FRAME_NUMBER) != pThis->m_nNextFrame) 77 | { 78 | // do nothing 79 | } 80 | } 81 | 82 | _DWHCIRegister (&FrameNumber); 83 | } 84 | 85 | boolean DWHCIFrameSchedulerNoSplitIsOddFrame (TDWHCIFrameScheduler *pBase) 86 | { 87 | TDWHCIFrameSchedulerNoSplit *pThis = (TDWHCIFrameSchedulerNoSplit *) pBase; 88 | assert (pThis != 0); 89 | 90 | return pThis->m_nNextFrame & 1 ? TRUE : FALSE; 91 | } 92 | -------------------------------------------------------------------------------- /source/uspi_dwhciregister.c: -------------------------------------------------------------------------------- 1 | // 2 | // dwhciregister.c 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | #include 22 | #include 23 | 24 | void DWHCIRegister (TDWHCIRegister *pThis, u32 nAddress) 25 | { 26 | assert (pThis != 0); 27 | pThis->m_bValid = FALSE; 28 | pThis->m_nAddress = nAddress; 29 | } 30 | 31 | void DWHCIRegister2 (TDWHCIRegister *pThis, u32 nAddress, u32 nValue) 32 | { 33 | assert (pThis != 0); 34 | pThis->m_bValid = TRUE; 35 | pThis->m_nAddress = nAddress; 36 | pThis->m_nBuffer = nValue; 37 | } 38 | 39 | void _DWHCIRegister (TDWHCIRegister *pThis) 40 | { 41 | assert (pThis != 0); 42 | pThis->m_bValid = FALSE; 43 | } 44 | 45 | u32 DWHCIRegisterRead (TDWHCIRegister *pThis) 46 | { 47 | assert (pThis != 0); 48 | pThis->m_nBuffer = *(u32 *) pThis->m_nAddress; 49 | pThis->m_bValid = TRUE; 50 | 51 | return pThis->m_nBuffer; 52 | } 53 | 54 | void DWHCIRegisterWrite (TDWHCIRegister *pThis) 55 | { 56 | assert (pThis != 0); 57 | assert (pThis->m_bValid); 58 | *(u32 *) pThis->m_nAddress = pThis->m_nBuffer; 59 | } 60 | 61 | u32 DWHCIRegisterGet (TDWHCIRegister *pThis) 62 | { 63 | assert (pThis != 0); 64 | assert (pThis->m_bValid); 65 | return pThis->m_nBuffer; 66 | } 67 | 68 | void DWHCIRegisterSet (TDWHCIRegister *pThis, u32 nValue) 69 | { 70 | assert (pThis != 0); 71 | pThis->m_nBuffer = nValue; 72 | pThis->m_bValid = TRUE; 73 | } 74 | 75 | boolean DWHCIRegisterIsSet (TDWHCIRegister *pThis, u32 nMask) 76 | { 77 | assert (pThis != 0); 78 | assert (pThis->m_bValid); 79 | return pThis->m_nBuffer & nMask ? TRUE : FALSE; 80 | } 81 | 82 | void DWHCIRegisterAnd (TDWHCIRegister *pThis, u32 nMask) 83 | { 84 | assert (pThis != 0); 85 | assert (pThis->m_bValid); 86 | pThis->m_nBuffer &= nMask; 87 | } 88 | 89 | void DWHCIRegisterOr (TDWHCIRegister *pThis, u32 nMask) 90 | { 91 | assert (pThis != 0); 92 | assert (pThis->m_bValid); 93 | pThis->m_nBuffer |= nMask; 94 | } 95 | 96 | void DWHCIRegisterClearBit (TDWHCIRegister *pThis, unsigned nBit) 97 | { 98 | assert (pThis != 0); 99 | assert (pThis->m_bValid); 100 | assert (nBit < sizeof pThis->m_nBuffer * 8); 101 | pThis->m_nBuffer &= ~(1 << nBit); 102 | } 103 | 104 | void DWHCIRegisterSetBit (TDWHCIRegister *pThis, unsigned nBit) 105 | { 106 | assert (pThis != 0); 107 | assert (pThis->m_bValid); 108 | assert (nBit < sizeof pThis->m_nBuffer * 8); 109 | pThis->m_nBuffer |= 1 << nBit; 110 | } 111 | 112 | void DWHCIRegisterClearAll (TDWHCIRegister *pThis) 113 | { 114 | assert (pThis != 0); 115 | pThis->m_nBuffer = 0; 116 | pThis->m_bValid = TRUE; 117 | } 118 | 119 | void DWHCIRegisterSetAll (TDWHCIRegister *pThis) 120 | { 121 | assert (pThis != 0); 122 | pThis->m_nBuffer = (u32) -1; 123 | pThis->m_bValid = TRUE; 124 | } 125 | 126 | #ifndef NDEBUG 127 | 128 | void DWHCIRegisterDump (TDWHCIRegister *pThis) 129 | { 130 | assert (pThis != 0); 131 | if (pThis->m_bValid) 132 | { 133 | LogWrite ("dwhci", LOG_DEBUG, 134 | "Register at 0x%X is 0x%X", 135 | pThis->m_nAddress & 0xFFF, pThis->m_nBuffer); 136 | } 137 | else 138 | { 139 | LogWrite ("dwhci", LOG_DEBUG, 140 | "Register at 0x%X was not set", 141 | pThis->m_nAddress & 0xFFF); 142 | } 143 | } 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /source/uspi_dwhcirootport.c: -------------------------------------------------------------------------------- 1 | // 2 | // dwhcirootport.cpp 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | static const char FromDWHCIRoot[] = "dwroot"; 28 | 29 | void DWHCIRootPort (TDWHCIRootPort *pThis, struct TDWHCIDevice *pHost) 30 | { 31 | assert (pThis != 0); 32 | 33 | pThis->m_pHost = pHost; 34 | pThis->m_pDevice = 0; 35 | 36 | assert (pThis->m_pHost != 0); 37 | } 38 | 39 | void _DWHCIRootPort (TDWHCIRootPort *pThis) 40 | { 41 | assert (pThis != 0); 42 | 43 | if (pThis->m_pDevice != 0) 44 | { 45 | _USBDevice (pThis->m_pDevice); 46 | free (pThis->m_pDevice); 47 | pThis->m_pDevice = 0; 48 | } 49 | 50 | pThis->m_pHost = 0; 51 | } 52 | 53 | boolean DWHCIRootPortInitialize (TDWHCIRootPort *pThis) 54 | { 55 | assert (pThis != 0); 56 | 57 | assert (pThis->m_pHost != 0); 58 | TUSBSpeed Speed = DWHCIDeviceGetPortSpeed (pThis->m_pHost); 59 | if (Speed == USBSpeedUnknown) 60 | { 61 | LogWrite (FromDWHCIRoot, LOG_ERROR, "Cannot detect port speed"); 62 | 63 | return FALSE; 64 | } 65 | 66 | // first create default device 67 | assert (pThis->m_pDevice == 0); 68 | pThis->m_pDevice = (TUSBDevice *) malloc (sizeof (TUSBDevice)); 69 | assert (pThis->m_pDevice != 0); 70 | USBDevice (pThis->m_pDevice, pThis->m_pHost, Speed, 0, 1); 71 | 72 | if (!USBDeviceInitialize (pThis->m_pDevice)) 73 | { 74 | _USBDevice (pThis->m_pDevice); 75 | free (pThis->m_pDevice); 76 | pThis->m_pDevice = 0; 77 | 78 | return FALSE; 79 | } 80 | 81 | TString *pNames = USBStandardHubGetDeviceNames (pThis->m_pDevice); 82 | assert (pNames != 0); 83 | 84 | LogWrite (FromDWHCIRoot, LOG_NOTICE, "Device %s found", StringGet (pNames)); 85 | 86 | _String (pNames); 87 | free (pNames); 88 | 89 | // now create specific device from default device 90 | TUSBDevice *pChild = USBDeviceFactoryGetDevice (pThis->m_pDevice); 91 | if (pChild != 0) 92 | { 93 | _USBDevice (pThis->m_pDevice); // delete default device 94 | free (pThis->m_pDevice); 95 | pThis->m_pDevice = pChild; // assign specific device 96 | 97 | if (!(*pThis->m_pDevice->Configure) (pThis->m_pDevice)) 98 | { 99 | LogWrite (FromDWHCIRoot, LOG_ERROR, "Cannot configure device"); 100 | 101 | _USBDevice (pThis->m_pDevice); 102 | free (pThis->m_pDevice); 103 | pThis->m_pDevice = 0; 104 | 105 | return FALSE; 106 | } 107 | 108 | LogWrite (FromDWHCIRoot, LOG_DEBUG, "Device configured"); 109 | } 110 | else 111 | { 112 | LogWrite (FromDWHCIRoot, LOG_NOTICE, "Device is not supported"); 113 | 114 | _USBDevice (pThis->m_pDevice); 115 | free (pThis->m_pDevice); 116 | pThis->m_pDevice = 0; 117 | 118 | return FALSE; 119 | } 120 | 121 | // check for over-current 122 | if (DWHCIDeviceOvercurrentDetected (pThis->m_pHost)) 123 | { 124 | LogWrite (FromDWHCIRoot, LOG_ERROR, "Over-current condition"); 125 | 126 | DWHCIDeviceDisableRootPort (pThis->m_pHost); 127 | 128 | _USBDevice (pThis->m_pDevice); 129 | free (pThis->m_pDevice); 130 | pThis->m_pDevice = 0; 131 | 132 | return FALSE; 133 | } 134 | 135 | return TRUE; 136 | } 137 | -------------------------------------------------------------------------------- /source/uspi_macaddress.c: -------------------------------------------------------------------------------- 1 | // 2 | // macaddress.h 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | #include 22 | #include 23 | 24 | void MACAddress (TMACAddress *pThis) 25 | { 26 | assert (pThis != 0); 27 | 28 | pThis->m_bValid = FALSE; 29 | } 30 | 31 | void MACAddress2 (TMACAddress *pThis, const u8 *pAddress) 32 | { 33 | assert (pThis != 0); 34 | 35 | MACAddressSet (pThis, pAddress); 36 | } 37 | 38 | void _MACAddress (TMACAddress *pThis) 39 | { 40 | assert (pThis != 0); 41 | 42 | pThis->m_bValid = FALSE; 43 | } 44 | 45 | boolean MACAddressIsEqual (TMACAddress *pThis, TMACAddress *pAddress2) 46 | { 47 | assert (pThis != 0); 48 | assert (pThis->m_bValid); 49 | 50 | return memcmp (pThis->m_Address, MACAddressGet (pAddress2), MAC_ADDRESS_SIZE) == 0 ? TRUE : FALSE; 51 | } 52 | 53 | void MACAddressSet (TMACAddress *pThis, const u8 *pAddress) 54 | { 55 | assert (pThis != 0); 56 | assert (pAddress != 0); 57 | 58 | memcpy (pThis->m_Address, pAddress, MAC_ADDRESS_SIZE); 59 | pThis->m_bValid = TRUE; 60 | } 61 | 62 | void MACAddressSetBroadcast (TMACAddress *pThis) 63 | { 64 | assert (pThis != 0); 65 | 66 | memset (pThis->m_Address, 0xFF, MAC_ADDRESS_SIZE); 67 | pThis->m_bValid = TRUE; 68 | } 69 | 70 | const u8 *MACAddressGet (TMACAddress *pThis) 71 | { 72 | assert (pThis != 0); 73 | assert (pThis->m_bValid); 74 | 75 | return pThis->m_Address; 76 | } 77 | 78 | void MACAddressCopyTo (TMACAddress *pThis, u8 *pBuffer) 79 | { 80 | assert (pThis != 0); 81 | assert (pThis->m_bValid); 82 | assert (pBuffer != 0); 83 | 84 | memcpy (pBuffer, pThis->m_Address, MAC_ADDRESS_SIZE); 85 | } 86 | 87 | boolean MACAddressIsBroadcast (TMACAddress *pThis) 88 | { 89 | assert (pThis != 0); 90 | assert (pThis->m_bValid); 91 | 92 | for (unsigned i = 0; i < MAC_ADDRESS_SIZE; i++) 93 | { 94 | if (pThis->m_Address[i] != 0xFF) 95 | { 96 | return FALSE; 97 | } 98 | } 99 | 100 | return TRUE; 101 | } 102 | 103 | unsigned MACAddressGetSize (TMACAddress *pThis) 104 | { 105 | return MAC_ADDRESS_SIZE; 106 | } 107 | 108 | void MACAddressFormat (TMACAddress *pThis, TString *pString) 109 | { 110 | assert (pThis != 0); 111 | assert (pThis->m_bValid); 112 | 113 | assert (pString != 0); 114 | StringFormat (pString, "%02X:%02X:%02X:%02X:%02X:%02X", 115 | (unsigned) pThis->m_Address[0], (unsigned) pThis->m_Address[1], 116 | (unsigned) pThis->m_Address[2], (unsigned) pThis->m_Address[3], 117 | (unsigned) pThis->m_Address[4], (unsigned) pThis->m_Address[5]); 118 | } 119 | -------------------------------------------------------------------------------- /source/uspi_synchronize.c: -------------------------------------------------------------------------------- 1 | // 2 | // synchronize.c 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014-2015 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | #include 22 | #include 23 | 24 | #define EnableInterrupts() __asm volatile ("cpsie i") 25 | #define DisableInterrupts() __asm volatile ("cpsid i") 26 | 27 | static volatile unsigned s_nCriticalLevel = 0; 28 | static volatile boolean s_bWereEnabled; 29 | 30 | void uspi_EnterCritical (void) 31 | { 32 | u32 nFlags; 33 | asm volatile ("mrs %0, cpsr" : "=r" (nFlags)); 34 | 35 | DisableInterrupts (); 36 | 37 | if (s_nCriticalLevel++ == 0) 38 | { 39 | s_bWereEnabled = nFlags & 0x80 ? FALSE : TRUE; 40 | } 41 | 42 | DataMemBarrier (); 43 | } 44 | 45 | void uspi_LeaveCritical (void) 46 | { 47 | DataMemBarrier (); 48 | 49 | assert (s_nCriticalLevel > 0); 50 | if (--s_nCriticalLevel == 0) 51 | { 52 | if (s_bWereEnabled) 53 | { 54 | EnableInterrupts (); 55 | } 56 | } 57 | } 58 | 59 | #if RASPPI == 1 60 | 61 | // 62 | // Cache maintenance operations for ARMv6 63 | // 64 | // NOTE: The following functions should hold all variables in CPU registers. Currently this will be 65 | // ensured using maximum optimation (see circle/synchronize.h). 66 | // 67 | // The following numbers can be determined (dynamically) using CTR. 68 | // As long we use the ARM1176JZF-S implementation in the BCM2835 these static values will work: 69 | // 70 | 71 | #define DATA_CACHE_LINE_LENGTH 32 72 | 73 | void uspi_CleanAndInvalidateDataCacheRange (u32 nAddress, u32 nLength) 74 | { 75 | nLength += DATA_CACHE_LINE_LENGTH; 76 | 77 | while (1) 78 | { 79 | asm volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" (nAddress) : "memory"); 80 | 81 | if (nLength < DATA_CACHE_LINE_LENGTH) 82 | { 83 | break; 84 | } 85 | 86 | nAddress += DATA_CACHE_LINE_LENGTH; 87 | nLength -= DATA_CACHE_LINE_LENGTH; 88 | } 89 | } 90 | 91 | #else 92 | 93 | // 94 | // Cache maintenance operations for ARMv7-A 95 | // 96 | // See: ARMv7-A Architecture Reference Manual, Section B4.2.1 97 | // 98 | // NOTE: The following functions should hold all variables in CPU registers. Currently this will be 99 | // ensured using the register keyword and maximum optimation (see uspi/synchronize.h). 100 | // 101 | // The following numbers can be determined (dynamically) using CTR, CSSELR, CCSIDR and CLIDR. 102 | // As long we use the Cortex-A7 implementation in the BCM2836 or the Cortex-A53 implementation 103 | // in the BCM2837 these static values will work: 104 | // 105 | 106 | #define L1_DATA_CACHE_LINE_LENGTH 64 107 | #define L2_CACHE_LINE_LENGTH 64 108 | #define DATA_CACHE_LINE_LENGTH_MIN 64 // min(L1_DATA_CACHE_LINE_LENGTH, L2_CACHE_LINE_LENGTH) 109 | 110 | void uspi_CleanAndInvalidateDataCacheRange (u32 nAddress, u32 nLength) 111 | { 112 | nLength += DATA_CACHE_LINE_LENGTH_MIN; 113 | 114 | while (1) 115 | { 116 | __asm volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" (nAddress) : "memory"); // DCCIMVAC 117 | 118 | if (nLength < DATA_CACHE_LINE_LENGTH_MIN) 119 | { 120 | break; 121 | } 122 | 123 | nAddress += DATA_CACHE_LINE_LENGTH_MIN; 124 | nLength -= DATA_CACHE_LINE_LENGTH_MIN; 125 | } 126 | } 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /source/uspi_usbrequest.c: -------------------------------------------------------------------------------- 1 | // 2 | // usbrequest.c 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | #include 22 | 23 | void USBRequest (TUSBRequest *pThis, TUSBEndpoint *pEndpoint, void *pBuffer, u32 nBufLen, TSetupData *pSetupData) 24 | { 25 | assert (pThis != 0); 26 | 27 | pThis->m_pEndpoint = pEndpoint; 28 | pThis->m_pSetupData = pSetupData; 29 | pThis->m_pBuffer = pBuffer; 30 | pThis->m_nBufLen = nBufLen; 31 | pThis->m_bStatus = 0; 32 | pThis->m_nResultLen = 0; 33 | pThis->m_pCompletionRoutine = 0; 34 | pThis->m_pCompletionParam = 0; 35 | pThis->m_pCompletionContext = 0; 36 | 37 | assert (pThis->m_pEndpoint != 0); 38 | assert (pThis->m_pBuffer != 0 || pThis->m_nBufLen == 0); 39 | } 40 | 41 | void _USBRequest (TUSBRequest *pThis) 42 | { 43 | assert (pThis != 0); 44 | pThis->m_pEndpoint = 0; 45 | pThis->m_pSetupData = 0; 46 | pThis->m_pBuffer = 0; 47 | pThis->m_pCompletionRoutine = 0; 48 | } 49 | 50 | TUSBEndpoint *USBRequestGetEndpoint (TUSBRequest *pThis) 51 | { 52 | assert (pThis != 0); 53 | assert (pThis->m_pEndpoint != 0); 54 | return pThis->m_pEndpoint; 55 | } 56 | 57 | void USBRequestSetStatus (TUSBRequest *pThis, int bStatus) 58 | { 59 | assert (pThis != 0); 60 | pThis->m_bStatus = bStatus; 61 | } 62 | 63 | void USBRequestSetResultLen (TUSBRequest *pThis, u32 nLength) 64 | { 65 | assert (pThis != 0); 66 | pThis->m_nResultLen = nLength; 67 | } 68 | 69 | int USBRequestGetStatus (TUSBRequest *pThis) 70 | { 71 | assert (pThis != 0); 72 | return pThis->m_bStatus; 73 | } 74 | 75 | u32 USBRequestGetResultLength (TUSBRequest *pThis) 76 | { 77 | assert (pThis != 0); 78 | assert (pThis->m_bStatus); 79 | 80 | return pThis->m_nResultLen; 81 | } 82 | 83 | TSetupData *USBRequestGetSetupData (TUSBRequest *pThis) 84 | { 85 | assert (pThis != 0); 86 | assert (USBEndpointGetType (pThis->m_pEndpoint) == EndpointTypeControl); 87 | assert (pThis->m_pSetupData != 0); 88 | 89 | return pThis->m_pSetupData; 90 | } 91 | 92 | void *USBRequestGetBuffer (TUSBRequest *pThis) 93 | { 94 | assert (pThis != 0); 95 | assert ( pThis->m_pBuffer != 0 96 | || pThis->m_nBufLen == 0); 97 | 98 | return pThis->m_pBuffer; 99 | } 100 | 101 | u32 USBRequestGetBufLen (TUSBRequest *pThis) 102 | { 103 | assert (pThis != 0); 104 | return pThis->m_nBufLen; 105 | } 106 | 107 | void USBRequestSetCompletionRoutine (TUSBRequest *pThis, TURBCompletionRoutine *pRoutine, void *pParam, void *pContext) 108 | { 109 | assert (pThis != 0); 110 | pThis->m_pCompletionRoutine = pRoutine; 111 | pThis->m_pCompletionParam = pParam; 112 | pThis->m_pCompletionContext = pContext; 113 | 114 | assert (pThis->m_pCompletionRoutine != 0); 115 | } 116 | 117 | void USBRequestCallCompletionRoutine (TUSBRequest *pThis) 118 | { 119 | assert (pThis != 0); 120 | assert (pThis->m_pCompletionRoutine != 0); 121 | 122 | (*pThis->m_pCompletionRoutine) (pThis, pThis->m_pCompletionParam, pThis->m_pCompletionContext); 123 | } 124 | -------------------------------------------------------------------------------- /source/uspi_util.c: -------------------------------------------------------------------------------- 1 | // 2 | // util.c 3 | // 4 | // Circle - A C++ bare metal environment for Raspberry Pi 5 | // Copyright (C) 2014 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | 22 | #ifdef USPI_PROVIDE_MEM_FUNCTIONS 23 | 24 | void *uspi_memset (void *pBuffer, int nValue, size_t nLength) 25 | { 26 | char *p = (char *) pBuffer; 27 | 28 | while (nLength--) 29 | { 30 | *p++ = (char) nValue; 31 | } 32 | 33 | return pBuffer; 34 | } 35 | 36 | void *uspi_memcpy (void *pDest, const void *pSrc, size_t nLength) 37 | { 38 | char *pd = (char *) pDest; 39 | char *ps = (char *) pSrc; 40 | 41 | while (nLength--) 42 | { 43 | *pd++ = *ps++; 44 | } 45 | 46 | return pDest; 47 | } 48 | 49 | int uspi_memcmp (const void *pBuffer1, const void *pBuffer2, size_t nLength) 50 | { 51 | const unsigned char *p1 = (const unsigned char *) pBuffer1; 52 | const unsigned char *p2 = (const unsigned char *) pBuffer2; 53 | 54 | while (nLength-- > 0) 55 | { 56 | if (*p1 > *p2) 57 | { 58 | return 1; 59 | } 60 | else if (*p1 < *p2) 61 | { 62 | return -1; 63 | } 64 | 65 | p1++; 66 | p2++; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | #endif 73 | 74 | #ifdef USPI_PROVIDE_STR_FUNCTIONS 75 | 76 | size_t uspi_strlen (const char *pString) 77 | { 78 | size_t nResult = 0; 79 | 80 | while (*pString++) 81 | { 82 | nResult++; 83 | } 84 | 85 | return nResult; 86 | } 87 | 88 | int uspi_strcmp (const char *pString1, const char *pString2) 89 | { 90 | while ( *pString1 != '\0' 91 | && *pString2 != '\0') 92 | { 93 | if (*pString1 > *pString2) 94 | { 95 | return 1; 96 | } 97 | else if (*pString1 < *pString2) 98 | { 99 | return -1; 100 | } 101 | 102 | pString1++; 103 | pString2++; 104 | } 105 | 106 | if (*pString1 > *pString2) 107 | { 108 | return 1; 109 | } 110 | else if (*pString1 < *pString2) 111 | { 112 | return -1; 113 | } 114 | 115 | return 0; 116 | } 117 | 118 | char *uspi_strcpy (char *pDest, const char *pSrc) 119 | { 120 | char *p = pDest; 121 | 122 | while (*pSrc) 123 | { 124 | *p++ = *pSrc++; 125 | } 126 | 127 | *p = '\0'; 128 | 129 | return pDest; 130 | } 131 | 132 | char *uspi_strncpy (char *pDest, const char *pSrc, size_t nMaxLen) 133 | { 134 | char *pResult = pDest; 135 | 136 | while (nMaxLen > 0) 137 | { 138 | if (*pSrc == '\0') 139 | { 140 | break; 141 | } 142 | 143 | *pDest++ = *pSrc++; 144 | nMaxLen--; 145 | } 146 | 147 | if (nMaxLen > 0) 148 | { 149 | *pDest = '\0'; 150 | } 151 | 152 | return pResult; 153 | } 154 | 155 | char *uspi_strcat (char *pDest, const char *pSrc) 156 | { 157 | char *p = pDest; 158 | 159 | while (*p) 160 | { 161 | p++; 162 | } 163 | 164 | while (*pSrc) 165 | { 166 | *p++ = *pSrc++; 167 | } 168 | 169 | *p = '\0'; 170 | 171 | return pDest; 172 | } 173 | 174 | #endif 175 | 176 | int uspi_char2int (char chValue) 177 | { 178 | int nResult = chValue; 179 | 180 | if (nResult > 0x7F) 181 | { 182 | nResult |= -0x100; 183 | } 184 | 185 | return nResult; 186 | } 187 | 188 | u16 uspi_le2be16 (u16 usValue) 189 | { 190 | return ((usValue & 0x00FF) << 8) 191 | | ((usValue & 0xFF00) >> 8); 192 | } 193 | 194 | u32 uspi_le2be32 (u32 ulValue) 195 | { 196 | return ((ulValue & 0x000000FF) << 24) 197 | | ((ulValue & 0x0000FF00) << 8) 198 | | ((ulValue & 0x00FF0000) >> 8) 199 | | ((ulValue & 0xFF000000) >> 24); 200 | } 201 | -------------------------------------------------------------------------------- /source/uspienv_delayloop.S: -------------------------------------------------------------------------------- 1 | /* 2 | * delayloop.S 3 | */ 4 | 5 | .text 6 | 7 | .align 3 8 | 9 | .globl DelayLoop 10 | DelayLoop: 11 | subs r0, r0, #1 12 | bhi DelayLoop 13 | mov pc, lr 14 | 15 | /* End */ 16 | -------------------------------------------------------------------------------- /source/uspienv_memio.c: -------------------------------------------------------------------------------- 1 | // 2 | // memio.cpp 3 | // 4 | // USPi - An USB driver for Raspberry Pi written in C 5 | // Copyright (C) 2014-2018 R. Stange 6 | // 7 | // This program is free software: you can redistribute it and/or modify 8 | // it under the terms of the GNU General Public License as published by 9 | // the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | #include 21 | 22 | u32 read32 (u32 nAddress) 23 | { 24 | return *(volatile u32 *) nAddress; 25 | } 26 | 27 | void write32 (u32 nAddress, u32 nValue) 28 | { 29 | *(volatile u32 *) nAddress = nValue; 30 | } 31 | -------------------------------------------------------------------------------- /uprogs/LICENSE: -------------------------------------------------------------------------------- 1 | The xv6 software is: 2 | 3 | Copyright (c) 2006-2009 Frans Kaashoek, Robert Morris, Russ Cox, 4 | Massachusetts Institute of Technology 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | -------------------------------------------------------------------------------- /uprogs/Makefile: -------------------------------------------------------------------------------- 1 | # Cross-compiling (e.g., on Mac OS X) 2 | #TOOLPREFIX = i386-jos-elf- 3 | # Using native tools (e.g., on X86 Linux) 4 | #TOOLPREFIX = ~/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi- 5 | 6 | 7 | # The intermediate directory for compiled object files. 8 | BUILD = build/ 9 | 10 | CC = $(TOOLPREFIX)gcc 11 | AS = $(TOOLPREFIX)as 12 | LD = $(TOOLPREFIX)ld 13 | OBJCOPY = $(TOOLPREFIX)objcopy 14 | OBJDUMP = $(TOOLPREFIX)objdump 15 | #CFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -fshort-wchar -O2 -Wall -MD -ggdb -Werror -fno-omit-frame-pointer -fno-stack-protector -Wa,-march=armv6 -Wa,-mcpu=arm1176jzf-s 16 | CFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -fshort-wchar -O2 -Wall -MD -ggdb -Werror -fno-omit-frame-pointer -fno-stack-protector -march=armv7-a 17 | 18 | all: mkfs initcode fs.img 19 | 20 | initcode: initcode.S 21 | $(CC) $(CFLAGS) -nostdinc -I. -c initcode.S 22 | $(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o 23 | $(OBJCOPY) -S -O binary initcode.out initcode 24 | $(OBJDUMP) -S initcode.o > initcode.asm 25 | 26 | 27 | ULIB = ulib.o usys.o printf.o umalloc.o 28 | 29 | _%: %.o $(ULIB) 30 | $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^ 31 | $(OBJDUMP) -S $@ > $*.asm 32 | $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym 33 | 34 | _forktest: forktest.o $(ULIB) 35 | # forktest has less library code linked in - needs to be small 36 | # in order to be able to max out the proc table. 37 | $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o 38 | $(OBJDUMP) -S _forktest > forktest.asm 39 | 40 | mkfs: mkfs.c ../include/fs.h 41 | gcc -o mkfs mkfs.c 42 | #gcc -Werror -Wall -o mkfs mkfs.c 43 | 44 | # Prevent deletion of intermediate files, e.g. cat.o, after first build, so 45 | # that disk image changes after first build are persistent until clean. More 46 | # details: 47 | # http://www.gnu.org/software/make/manual/html_node/Chained-Rules.html 48 | .PRECIOUS: %.o 49 | 50 | UPROGS=\ 51 | _cat\ 52 | _echo\ 53 | _forktest\ 54 | _grep\ 55 | _init\ 56 | _kill\ 57 | _ln\ 58 | _ls\ 59 | _mkdir\ 60 | _rm\ 61 | _sh\ 62 | _stressfs\ 63 | _usertests\ 64 | _wc\ 65 | _zombie\ 66 | _timetest\ 67 | _benchmark\ 68 | 69 | fs.img: mkfs README $(UPROGS) 70 | ./mkfs fs.img README $(UPROGS) 71 | 72 | clean: 73 | rm -f *.o *.d *.asm *.sym fs.img mkfs initcode initcode.out $(UPROGS) 74 | -------------------------------------------------------------------------------- /uprogs/README: -------------------------------------------------------------------------------- 1 | xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix 2 | Version 6 (v6). xv6 loosely follows the structure and style of v6, 3 | but is implemented for a modern x86-based multiprocessor using ANSI C. 4 | 5 | ACKNOWLEDGMENTS 6 | 7 | xv6 is inspired by John Lions's Commentary on UNIX 6th Edition (Peer 8 | to Peer Communications; ISBN: 1-57398-013-7; 1st edition (June 14, 9 | 2000)). See also http://pdos.csail.mit.edu/6.828/2012/v6.html, which 10 | provides pointers to on-line resources for v6. 11 | 12 | xv6 borrows code from the following sources: 13 | JOS (asm.h, elf.h, mmu.h, bootasm.S, ide.c, console.c, and others) 14 | Plan 9 (entryother.S, mp.h, mp.c, lapic.c) 15 | FreeBSD (ioapic.c) 16 | NetBSD (console.c) 17 | 18 | The following people have made contributions: 19 | Russ Cox (context switching, locking) 20 | Cliff Frey (MP) 21 | Xiao Yu (MP) 22 | Nickolai Zeldovich 23 | Austin Clements 24 | 25 | In addition, we are grateful for the patches contributed by Greg 26 | Price, Yandong Mao, and Hitoshi Mitake. 27 | 28 | The code in the files that constitute xv6 is 29 | Copyright 2006-2012 Frans Kaashoek, Robert Morris, and Russ Cox. 30 | 31 | ERROR REPORTS 32 | 33 | If you spot errors or have suggestions for improvement, please send 34 | email to Frans Kaashoek and Robert Morris (kaashoek,rtm@csail.mit.edu). 35 | 36 | BUILDING AND RUNNING XV6 37 | 38 | To build xv6 on an x86 ELF machine (like Linux or FreeBSD), run "make". 39 | On non-x86 or non-ELF machines (like OS X, even on x86), you will 40 | need to install a cross-compiler gcc suite capable of producing x86 ELF 41 | binaries. See http://pdos.csail.mit.edu/6.828/2012/tools.html. 42 | Then run "make TOOLPREFIX=i386-jos-elf-". 43 | 44 | To run xv6, you can use the Bochs or QEMU PC simulators. Bochs makes 45 | debugging easier, but QEMU is much faster. To run in Bochs, run "make 46 | bochs" and then type "c" at the bochs prompt. To run in QEMU, run 47 | "make qemu". 48 | 49 | To create a typeset version of the code, run "make xv6.pdf". This 50 | requires the "mpage" utility. See http://www.mesa.nl/pub/mpage/. 51 | -------------------------------------------------------------------------------- /uprogs/arm.h: -------------------------------------------------------------------------------- 1 | //PAGEBREAK: 36 2 | // Layout of the trap frame built on the stack by the 3 | // hardware and by trapasm.S, and passed to trap(). 4 | struct trapframe { 5 | uint trapno; 6 | uint spsr; // saved cpsr from the trapped/interrupted mode 7 | uint ifar; // Instruction Fault Address Register (IFAR) 8 | uint cpsr; 9 | uint sp; // user mode sp 10 | uint lr; // return address of the interrupted code 11 | uint r12; 12 | uint r11; 13 | uint r10; 14 | uint r9; 15 | uint r8; 16 | uint r7; 17 | uint r6; 18 | uint r5; 19 | uint r4; 20 | uint r3; 21 | uint r2; 22 | uint r1; 23 | uint r0; 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /uprogs/benchmark.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | 5 | #define FORK_BENCH 'f' 6 | #define FIB_BENCH 'i' 7 | #define SUM_BENCH 's' 8 | 9 | #define FIB_N 20 10 | #define SUM_FILE "benchmark" 11 | #define SUM_BUF_SIZE 10000 12 | 13 | void sum() { 14 | int i = 1; 15 | int sum = 0; 16 | int len; 17 | int pid; 18 | char* buf; 19 | int fd; 20 | while ((fd = open(SUM_FILE, 0)) < 0) { 21 | } 22 | buf = malloc(SUM_BUF_SIZE); 23 | if (buf == 0) { 24 | printf(1, "Malloc failure\n"); 25 | exit(); 26 | } 27 | len = read(fd, buf, SUM_BUF_SIZE); 28 | while ((i + 1) * len < SUM_BUF_SIZE) { 29 | memmove((void*) (buf + i * len), (void*) buf, len); 30 | i++; 31 | } 32 | while ((pid = fork()) == -1) { 33 | } 34 | if (!pid) { 35 | for (i = 0; i < SUM_BUF_SIZE / 2; i++) { 36 | sum += buf[i]; 37 | } 38 | exit(); 39 | } else { 40 | for (i = SUM_BUF_SIZE / 2; i < SUM_BUF_SIZE; i++) { 41 | sum += buf[i]; 42 | } 43 | } 44 | free(buf); 45 | close(fd); 46 | wait(); 47 | return; 48 | } 49 | 50 | int sum_bench(int n) { 51 | int start = time(); 52 | int i; 53 | int pid; 54 | for (i = 0; i < n; i++) { 55 | while ((pid = fork()) == -1) { 56 | } 57 | if (!pid) { 58 | sum(); 59 | exit(); 60 | } 61 | } 62 | for (i = 0; i < n; i++) { 63 | wait(); 64 | } 65 | return time() - start; 66 | } 67 | 68 | int fib(int n) { 69 | if (n <= 2) { 70 | return 1; 71 | } 72 | return fib(n - 1) + fib (n - 2); 73 | } 74 | 75 | int fib_bench(int n) { 76 | int i; 77 | int j; 78 | int pid; 79 | int start = time(); 80 | j = 0; 81 | for (i = 0; i < n; i++) { 82 | while ((pid = fork()) == -1) { 83 | wait(); 84 | j++; 85 | } 86 | if (!pid) { 87 | fib(FIB_N); 88 | exit(); 89 | } 90 | } 91 | for (i = 0; i < n - j; i++) { 92 | wait(); 93 | } 94 | int end = time(); 95 | return end - start; 96 | } 97 | 98 | int fork_bench(int n) { 99 | int i; 100 | int j; 101 | int pid; 102 | int start = time(); 103 | j = 0; 104 | for (i = 0 ; i < n; i++) { 105 | while ((pid = fork()) == -1) { 106 | wait(); 107 | j++; 108 | } 109 | if (!pid) { 110 | exit(); 111 | } 112 | } 113 | for (i = 0; i < n - j; i++) { 114 | wait(); 115 | } 116 | int end = time(); 117 | int time = end - start; 118 | return time; 119 | } 120 | 121 | int main(int argc, char* argv[]) { 122 | if (argc < 3) { 123 | printf(1, "Usage: \"benchmark [test] [n]\""); 124 | exit(); 125 | } 126 | char benchmark = argv[1][0]; 127 | int n = atoi(argv[2]); 128 | int score; 129 | switch (benchmark) { 130 | case FORK_BENCH: 131 | score = fork_bench(n); 132 | printf(1, "Benchmark Fork %d score: %d uS\n", n, score); 133 | break; 134 | case FIB_BENCH: 135 | score = fib_bench(n); 136 | printf(1, "Benchmark Fib %d score: %d uS\n", n, score); 137 | break; 138 | case SUM_BENCH: 139 | score = sum_bench(n); 140 | printf(1, "Benchmark Sum %d score: %d uS\n", n, score); 141 | break; 142 | default: 143 | break; 144 | } 145 | exit(); 146 | } 147 | -------------------------------------------------------------------------------- /uprogs/buf.h: -------------------------------------------------------------------------------- 1 | struct buf { 2 | int flags; 3 | uint dev; 4 | uint sector; 5 | struct buf *prev; // LRU cache list 6 | struct buf *next; 7 | struct buf *qnext; // disk queue 8 | uchar data[512]; 9 | }; 10 | #define B_BUSY 0x1 // buffer is locked by some process 11 | #define B_VALID 0x2 // buffer has been read from disk 12 | #define B_DIRTY 0x4 // buffer needs to be written to disk 13 | 14 | -------------------------------------------------------------------------------- /uprogs/cat.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | 5 | char buf[512]; 6 | 7 | void 8 | cat(int fd) 9 | { 10 | int n; 11 | while((n = read(fd, buf, sizeof(buf))) > 0) 12 | write(1, buf, n); 13 | if(n < 0){ 14 | printf(1, "cat: read error\n"); 15 | exit(); 16 | } 17 | } 18 | 19 | int 20 | main(int argc, char *argv[]) 21 | { 22 | int fd, i; 23 | 24 | if(argc <= 1){ 25 | cat(0); 26 | exit(); 27 | } 28 | 29 | for(i = 1; i < argc; i++){ 30 | if((fd = open(argv[i], 0)) < 0){ 31 | printf(1, "cat: cannot open %s\n", argv[i]); 32 | exit(); 33 | } 34 | cat(fd); 35 | close(fd); 36 | } 37 | exit(); 38 | } 39 | -------------------------------------------------------------------------------- /uprogs/echo.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | 5 | int 6 | main(int argc, char *argv[]) 7 | { 8 | int i; 9 | 10 | for(i = 1; i < argc; i++) 11 | printf(1, "%s%s", argv[i], i+1 < argc ? " " : "\n"); 12 | exit(); 13 | } 14 | -------------------------------------------------------------------------------- /uprogs/elf.h: -------------------------------------------------------------------------------- 1 | // Format of an ELF executable file 2 | 3 | #define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian 4 | 5 | // File header 6 | struct elfhdr { 7 | uint magic; // must equal ELF_MAGIC 8 | uchar elf[12]; 9 | ushort type; 10 | ushort machine; 11 | uint version; 12 | uint entry; 13 | uint phoff; 14 | uint shoff; 15 | uint flags; 16 | ushort ehsize; 17 | ushort phentsize; 18 | ushort phnum; 19 | ushort shentsize; 20 | ushort shnum; 21 | ushort shstrndx; 22 | }; 23 | 24 | // Program section header 25 | struct proghdr { 26 | uint type; 27 | uint off; 28 | uint vaddr; 29 | uint paddr; 30 | uint filesz; 31 | uint memsz; 32 | uint flags; 33 | uint align; 34 | }; 35 | 36 | // Values for Proghdr type 37 | #define ELF_PROG_LOAD 1 38 | 39 | // Flag bits for Proghdr flags 40 | #define ELF_PROG_FLAG_EXEC 1 41 | #define ELF_PROG_FLAG_WRITE 2 42 | #define ELF_PROG_FLAG_READ 4 43 | -------------------------------------------------------------------------------- /uprogs/fcntl.h: -------------------------------------------------------------------------------- 1 | #define O_RDONLY 0x000 2 | #define O_WRONLY 0x001 3 | #define O_RDWR 0x002 4 | #define O_CREATE 0x200 5 | -------------------------------------------------------------------------------- /uprogs/file.h: -------------------------------------------------------------------------------- 1 | struct file { 2 | enum { FD_NONE, FD_PIPE, FD_INODE } type; 3 | int ref; // reference count 4 | char readable; 5 | char writable; 6 | struct pipe *pipe; 7 | struct inode *ip; 8 | uint off; 9 | }; 10 | 11 | 12 | // in-memory copy of an inode 13 | struct inode { 14 | uint dev; // Device number 15 | uint inum; // Inode number 16 | int ref; // Reference count 17 | int flags; // I_BUSY, I_VALID 18 | 19 | short type; // copy of disk inode 20 | short major; 21 | short minor; 22 | short nlink; 23 | uint size; 24 | uint addrs[NDIRECT+1]; 25 | }; 26 | #define I_BUSY 0x1 27 | #define I_VALID 0x2 28 | 29 | // table mapping major device number to 30 | // device functions 31 | struct devsw { 32 | int (*read)(struct inode*, char*, int); 33 | int (*write)(struct inode*, char*, int); 34 | }; 35 | 36 | extern struct devsw devsw[]; 37 | 38 | #define CONSOLE 1 39 | -------------------------------------------------------------------------------- /uprogs/forktest.c: -------------------------------------------------------------------------------- 1 | // Test that fork fails gracefully. 2 | // Tiny executable so that the limit can be filling the proc table. 3 | 4 | #include "types.h" 5 | #include "stat.h" 6 | #include "user.h" 7 | 8 | #define N 1000 9 | 10 | void 11 | printf(int fd, char *s, ...) 12 | { 13 | write(fd, s, strlen(s)); 14 | } 15 | 16 | void 17 | forktest(void) 18 | { 19 | int n, pid; 20 | 21 | printf(1, "fork test\n"); 22 | 23 | for(n=0; n 0; n--){ 37 | if(wait() < 0){ 38 | printf(1, "wait stopped early\n"); 39 | exit(); 40 | } 41 | } 42 | 43 | if(wait() != -1){ 44 | printf(1, "wait got too many\n"); 45 | exit(); 46 | } 47 | 48 | printf(1, "fork test OK\n"); 49 | } 50 | 51 | int 52 | main(void) 53 | { 54 | forktest(); 55 | exit(); 56 | } 57 | -------------------------------------------------------------------------------- /uprogs/fs.h: -------------------------------------------------------------------------------- 1 | // On-disk file system format. 2 | // Both the kernel and user programs use this header file. 3 | 4 | // Block 0 is unused. 5 | // Block 1 is super block. 6 | // Blocks 2 through sb.ninodes/IPB hold inodes. 7 | // Then free bitmap blocks holding sb.size bits. 8 | // Then sb.nblocks data blocks. 9 | // Then sb.nlog log blocks. 10 | 11 | #define ROOTINO 1 // root i-number 12 | #define BSIZE 512 // block size 13 | 14 | // File system super block 15 | struct superblock { 16 | uint size; // Size of file system image (blocks) 17 | uint nblocks; // Number of data blocks 18 | uint ninodes; // Number of inodes. 19 | uint nlog; // Number of log blocks 20 | }; 21 | 22 | #define NDIRECT 12 23 | #define NINDIRECT (BSIZE / sizeof(uint)) 24 | #define MAXFILE (NDIRECT + NINDIRECT) 25 | 26 | // On-disk inode structure 27 | struct dinode { 28 | short type; // File type 29 | short major; // Major device number (T_DEV only) 30 | short minor; // Minor device number (T_DEV only) 31 | short nlink; // Number of links to inode in file system 32 | uint size; // Size of file (bytes) 33 | uint addrs[NDIRECT+1]; // Data block addresses 34 | }; 35 | 36 | // Inodes per block. 37 | #define IPB (BSIZE / sizeof(struct dinode)) 38 | 39 | // Block containing inode i 40 | #define IBLOCK(i) ((i) / IPB + 2) 41 | 42 | // Bitmap bits per block 43 | #define BPB (BSIZE*8) 44 | 45 | // Block containing bit for block b 46 | #define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3) 47 | 48 | // Directory is a file containing a sequence of dirent structures. 49 | #define DIRSIZ 14 50 | 51 | struct dirent { 52 | ushort inum; 53 | char name[DIRSIZ]; 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /uprogs/grep.c: -------------------------------------------------------------------------------- 1 | // Simple grep. Only supports ^ . * $ operators. 2 | 3 | #include "types.h" 4 | #include "stat.h" 5 | #include "user.h" 6 | 7 | char buf[1024]; 8 | int match(char*, char*); 9 | 10 | void 11 | grep(char *pattern, int fd) 12 | { 13 | int n, m; 14 | char *p, *q; 15 | 16 | m = 0; 17 | while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){ 18 | m += n; 19 | p = buf; 20 | while((q = strchr(p, '\n')) != 0){ 21 | *q = 0; 22 | if(match(pattern, p)){ 23 | *q = '\n'; 24 | write(1, p, q+1 - p); 25 | } 26 | p = q+1; 27 | } 28 | if(p == buf) 29 | m = 0; 30 | if(m > 0){ 31 | m -= p - buf; 32 | memmove(buf, p, m); 33 | } 34 | } 35 | } 36 | 37 | int 38 | main(int argc, char *argv[]) 39 | { 40 | int fd, i; 41 | char *pattern; 42 | 43 | if(argc <= 1){ 44 | printf(2, "usage: grep pattern [file ...]\n"); 45 | exit(); 46 | } 47 | pattern = argv[1]; 48 | 49 | if(argc <= 2){ 50 | grep(pattern, 0); 51 | exit(); 52 | } 53 | 54 | for(i = 2; i < argc; i++){ 55 | if((fd = open(argv[i], 0)) < 0){ 56 | printf(1, "grep: cannot open %s\n", argv[i]); 57 | exit(); 58 | } 59 | grep(pattern, fd); 60 | close(fd); 61 | } 62 | exit(); 63 | } 64 | 65 | // Regexp matcher from Kernighan & Pike, 66 | // The Practice of Programming, Chapter 9. 67 | 68 | int matchhere(char*, char*); 69 | int matchstar(int, char*, char*); 70 | 71 | int 72 | match(char *re, char *text) 73 | { 74 | if(re[0] == '^') 75 | return matchhere(re+1, text); 76 | do{ // must look at empty string 77 | if(matchhere(re, text)) 78 | return 1; 79 | }while(*text++ != '\0'); 80 | return 0; 81 | } 82 | 83 | // matchhere: search for re at beginning of text 84 | int matchhere(char *re, char *text) 85 | { 86 | if(re[0] == '\0') 87 | return 1; 88 | if(re[1] == '*') 89 | return matchstar(re[0], re+2, text); 90 | if(re[0] == '$' && re[1] == '\0') 91 | return *text == '\0'; 92 | if(*text!='\0' && (re[0]=='.' || re[0]==*text)) 93 | return matchhere(re+1, text+1); 94 | return 0; 95 | } 96 | 97 | // matchstar: search for c*re at beginning of text 98 | int matchstar(int c, char *re, char *text) 99 | { 100 | do{ // a * matches zero or more instances 101 | if(matchhere(re, text)) 102 | return 1; 103 | }while(*text!='\0' && (*text++==c || c=='.')); 104 | return 0; 105 | } 106 | 107 | -------------------------------------------------------------------------------- /uprogs/init.c: -------------------------------------------------------------------------------- 1 | // init: The initial user-level program 2 | 3 | #include "types.h" 4 | #include "stat.h" 5 | #include "user.h" 6 | #include "fcntl.h" 7 | 8 | char *argv[] = { "sh", 0 }; 9 | 10 | int 11 | main(void) 12 | { 13 | int pid, wpid; 14 | 15 | if(open("console", O_RDWR) < 0){ 16 | mknod("console", 1, 1); 17 | open("console", O_RDWR); 18 | } 19 | dup(0); // stdout 20 | dup(0); // stderr 21 | 22 | for(;;){ 23 | printf(1, "init: starting sh\n"); 24 | pid = fork(); 25 | if(pid < 0){ 26 | printf(1, "init: fork failed\n"); 27 | exit(); 28 | } 29 | if(pid == 0){ 30 | exec("sh", argv); 31 | printf(1, "init: exec sh failed\n"); 32 | exit(); 33 | } 34 | while((wpid=wait()) >= 0 && wpid != pid) 35 | printf(1, "zombie!\n"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /uprogs/initcode.S: -------------------------------------------------------------------------------- 1 | # Initial process execs /init. 2 | 3 | #include "syscall.h" 4 | #include "traps.h" 5 | 6 | 7 | # exec(init, argv) 8 | .globl start 9 | start: 10 | push {lr} 11 | ldr r0, =argv 12 | push {r0} 13 | ldr r0, =init 14 | push {r0} 15 | mov r0, #SYS_exec 16 | swi #T_SYSCALL 17 | pop {lr} 18 | pop {lr} 19 | pop {lr} 20 | bx lr 21 | 22 | # for(;;) exit(); 23 | exit: 24 | mov r11, #SYS_exit 25 | swi #T_SYSCALL 26 | bl exit 27 | 28 | # char init[] = "/init\0"; 29 | init: 30 | .string "/init\0" 31 | 32 | # char *argv[] = { init, 0 }; 33 | .p2align 2 34 | argv: 35 | .long init 36 | .long 0 37 | 38 | -------------------------------------------------------------------------------- /uprogs/kill.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | int i; 9 | 10 | if(argc < 1){ 11 | printf(2, "usage: kill pid...\n"); 12 | exit(); 13 | } 14 | for(i=1; i= path && *p != '/'; p--) 14 | ; 15 | p++; 16 | 17 | // Return blank-padded name. 18 | if(strlen(p) >= DIRSIZ) 19 | return p; 20 | memmove(buf, p, strlen(p)); 21 | memset(buf+strlen(p), ' ', DIRSIZ-strlen(p)); 22 | return buf; 23 | } 24 | 25 | void 26 | ls(char *path) 27 | { 28 | char buf[512], *p; 29 | int fd; 30 | struct dirent de; 31 | struct stat st; 32 | 33 | if((fd = open(path, 0)) < 0){ 34 | printf(2, "ls: cannot open %s\n", path); 35 | return; 36 | } 37 | 38 | if(fstat(fd, &st) < 0){ 39 | printf(2, "ls: cannot stat %s\n", path); 40 | close(fd); 41 | return; 42 | } 43 | 44 | switch(st.type){ 45 | case T_FILE: 46 | printf(1, "%s %d %d %d\n", fmtname(path), st.type, st.ino, st.size); 47 | break; 48 | 49 | case T_DIR: 50 | if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){ 51 | printf(1, "ls: path too long\n"); 52 | break; 53 | } 54 | strcpy(buf, path); 55 | p = buf+strlen(buf); 56 | *p++ = '/'; 57 | while(read(fd, &de, sizeof(de)) == sizeof(de)){ 58 | if(de.inum == 0) 59 | continue; 60 | memmove(p, de.name, DIRSIZ); 61 | p[DIRSIZ] = 0; 62 | if(stat(buf, &st) < 0){ 63 | printf(1, "ls: cannot stat %s\n", buf); 64 | continue; 65 | } 66 | printf(1, "%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size); 67 | } 68 | break; 69 | } 70 | close(fd); 71 | } 72 | 73 | int 74 | main(int argc, char *argv[]) 75 | { 76 | int i; 77 | 78 | if(argc < 2){ 79 | ls("."); 80 | exit(); 81 | } 82 | for(i=1; i>(o)) & ((1<<(w))-1)) 8 | #define L1X(va) FEXT((va), 20, 12) 9 | #define L2X(va) FEXT((va), 12, 8) 10 | 11 | /* 12 | * page table entries. 13 | */ 14 | 15 | #define Mbz (0<<4) 16 | #define Fault 0x00000000 /* L[12] pte: unmapped */ 17 | 18 | #define Coarse (Mbz|1) /* L1 */ 19 | #define Section (Mbz|2) /* L1 1MB */ 20 | #define Fine (Mbz|3) /* L1 */ 21 | 22 | #define Large 0x00000001 /* L2 64KB */ 23 | #define Small 0x00000002 /* L2 4KB */ 24 | #define Tiny 0x00000003 /* L2 1KB: not in v7 */ 25 | #define Buffered 0x00000004 /* L[12]: write-back not -thru */ 26 | #define Cached 0x00000008 /* L[12] */ 27 | #define Dom0 0 28 | 29 | #define Noaccess 0 /* AP, DAC */ 30 | #define Krw 1 /* AP */ 31 | /* armv7 deprecates AP[2] == 1 & AP[1:0] == 2 (Uro), prefers 3 (new in v7) */ 32 | #define Uro 2 /* AP */ 33 | #define Urw 3 /* AP */ 34 | #define Client 1 /* DAC */ 35 | #define Manager 3 /* DAC */ 36 | 37 | #define F(v, o, w) (((v) & ((1<<(w))-1))<<(o)) 38 | #define AP(n, v) F((v), ((n)*2)+4, 2) 39 | #define L1AP(ap) (AP(3, (ap))) 40 | #define L2AP(ap) (AP(3, (ap))|AP(2, (ap))|AP(1, (ap))|AP(0, (ap))) /* pre-armv7 */ 41 | #define DAC(n, v) F((v), (n)*2, 2) 42 | 43 | #define HVECTORS 0xffff0000 44 | 45 | // A virtual address 'la' has a three-part structure as follows: 46 | // 47 | // +--------12------+-------8--------+---------12----------+ 48 | // | Page Directory | Page Table | Offset within Page | 49 | // | Index | Index | | 50 | // +----------------+----------------+---------------------+ 51 | // \--- PDX(va) --/ \--- PTX(va) --/ 52 | 53 | // page directory index 54 | #define PDX(va) (((uint)(va) >> PDXSHIFT) & 0xFFF) 55 | 56 | // page table index 57 | #define PTX(va) (((uint)(va) >> PTXSHIFT) & 0xFF) 58 | 59 | // construct virtual address from indexes and offset 60 | #define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) 61 | 62 | // Address in page table or page directory entry 63 | #define PTE_ADDR(pte) ((uint)(pte) & ~0xFFF) 64 | #define PTE_FLAGS(pte) ((uint)(pte) & 0xFFF) 65 | 66 | // Page directory and page table constants. 67 | #define NPDENTRIES 1024 // # directory entries per page directory 68 | #define NPTENTRIES 1024 // # PTEs per page table 69 | #define PGSIZE 4096 // bytes mapped by a page 70 | 71 | #define PGSHIFT 12 // log2(PGSIZE) 72 | #define PTXSHIFT 12 // offset of PTX in a linear address 73 | #define PDXSHIFT 20 // offset of PDX in a linear address 74 | 75 | 76 | #define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) 77 | #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) 78 | 79 | #define PGDIR_BASE P2V(L1) 80 | 81 | #define KVML1ATTR Dom0|L1AP(Urw)|Section|Cached|Buffered 82 | 83 | #define UVML1ATTR Dom0|Coarse 84 | #define UVML2ATTR L2AP(Urw)|Cached|Buffered|Small 85 | 86 | #define USER_MODE 0 87 | -------------------------------------------------------------------------------- /uprogs/param.h: -------------------------------------------------------------------------------- 1 | #define NPROC 64 // maximum number of processes 2 | #define KSTACKSIZE 4096 // size of per-process kernel stack 3 | #define NCPU 8 // maximum number of CPUs 4 | #define NOFILE 16 // open files per process 5 | #define NFILE 100 // open files per system 6 | #define NBUF 10 // size of disk block cache 7 | #define NINODE 50 // maximum number of active i-nodes 8 | #define NDEV 10 // maximum major device number 9 | #define ROOTDEV 1 // device number of file system root disk 10 | #define MAXARG 32 // max exec arguments 11 | #define LOGSIZE 10 // max data sectors in on-disk log 12 | 13 | -------------------------------------------------------------------------------- /uprogs/printf.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | #include "param.h" 5 | 6 | #define BUFFERSIZE 512 7 | struct buffer { 8 | char data[BUFFERSIZE]; 9 | uint length; 10 | }; 11 | 12 | struct buffer writebuffer[NOFILE]; 13 | 14 | static void 15 | putc(int fd, char c) 16 | { 17 | if (fd >= NOFILE) { 18 | return; 19 | } 20 | writebuffer[fd].data[writebuffer[fd].length++] = c; 21 | if (c == '\0' || c == '\n'|| writebuffer[fd].length == BUFFERSIZE) { 22 | write(fd, &writebuffer[fd].data, writebuffer[fd].length); 23 | writebuffer[fd].length = 0; 24 | } 25 | // write(fd, &c, 1); 26 | } 27 | 28 | static void flushbuffer(int fd) { 29 | if (writebuffer[fd].length > 0) { 30 | write(fd, &writebuffer[fd].data, writebuffer[fd].length); 31 | writebuffer[fd].length = 0; 32 | } 33 | } 34 | 35 | u32 div(u32 n, u32 d) // long division 36 | { 37 | u32 q=0, r=0; 38 | int i; 39 | 40 | for(i=31;i>=0;i--){ 41 | r = r << 1; 42 | r = r | ((n >> i) & 1); 43 | if(r >= d) { 44 | r = r - d; 45 | q = q | (1 << i); 46 | } 47 | } 48 | return q; 49 | } 50 | 51 | static void 52 | printint(int fd, int xx, int base, int sgn) 53 | { 54 | static char digits[] = "0123456789ABCDEF"; 55 | char buf[16]; 56 | int i, neg; 57 | uint x, y, b; 58 | 59 | neg = 0; 60 | if(sgn && xx < 0){ 61 | neg = 1; 62 | x = -xx; 63 | } else { 64 | x = xx; 65 | } 66 | 67 | b = base; 68 | i = 0; 69 | do{ 70 | y = div(x, b); 71 | buf[i++] = digits[x - y * b]; 72 | }while((x = y) != 0); 73 | if(neg) 74 | buf[i++] = '-'; 75 | 76 | while(--i >= 0) 77 | putc(fd, buf[i]); 78 | } 79 | 80 | // Print to the given fd. Only understands %d, %x, %p, %s. 81 | void 82 | printf(int fd, char *fmt, ...) 83 | { 84 | char *s; 85 | int c, i, state; 86 | uint *ap; 87 | writebuffer[fd].length = 0; 88 | state = 0; 89 | ap = (uint*)(void*)&fmt + 1; 90 | for(i = 0; fmt[i]; i++){ 91 | c = fmt[i] & 0xff; 92 | if(state == 0){ 93 | if(c == '%'){ 94 | state = '%'; 95 | } else { 96 | putc(fd, c); 97 | } 98 | } else if(state == '%'){ 99 | if(c == 'd'){ 100 | printint(fd, *ap, 10, 1); 101 | ap++; 102 | } else if(c == 'x' || c == 'p'){ 103 | printint(fd, *ap, 16, 0); 104 | ap++; 105 | } else if(c == 's'){ 106 | s = (char*)*ap; 107 | ap++; 108 | if(s == 0) 109 | s = "(null)"; 110 | while(*s != 0){ 111 | putc(fd, *s); 112 | s++; 113 | } 114 | } else if(c == 'c'){ 115 | putc(fd, *ap); 116 | ap++; 117 | } else if(c == '%'){ 118 | putc(fd, c); 119 | } else { 120 | // Unknown % sequence. Print it to draw attention. 121 | putc(fd, '%'); 122 | putc(fd, c); 123 | } 124 | state = 0; 125 | } 126 | } 127 | flushbuffer(fd); 128 | } 129 | -------------------------------------------------------------------------------- /uprogs/proc.h: -------------------------------------------------------------------------------- 1 | // Segments in proc->gdt. 2 | #define NSEGS 7 3 | 4 | // Per-CPU state 5 | struct cpu { 6 | uchar id; // Local APIC ID; index into cpus[] below 7 | struct context *scheduler; // swtch() here to enter scheduler 8 | volatile uint started; // Has the CPU started? 9 | int ncli; // Depth of pushcli nesting. 10 | int intena; // Were interrupts enabled before pushcli? 11 | 12 | // Cpu-local storage variables; see below 13 | struct cpu *cpu; 14 | struct proc *proc; // The currently-running process. 15 | }; 16 | 17 | struct cpu cpus[NCPU]; 18 | //extern int ncpu; 19 | 20 | // Per-CPU variables, holding pointers to the 21 | // current cpu and to the current process. 22 | // The asm suffix tells gcc to use "%gs:0" to refer to cpu 23 | // and "%gs:4" to refer to proc. seginit sets up the 24 | // %gs segment register so that %gs refers to the memory 25 | // holding those two variables in the local cpu's struct cpu. 26 | // This is similar to how thread-local variables are implemented 27 | // in thread libraries such as Linux pthreads. 28 | //extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()] 29 | //extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc 30 | 31 | #define curr_cpu (&cpus[0]) 32 | #define curr_proc (cpus[0].proc) 33 | 34 | //PAGEBREAK: 17 35 | // Saved registers for kernel context switches. 36 | // Don't need to save all the segment registers (%cs, etc), 37 | // because they are constant across kernel contexts. 38 | // Don't need to save %eax, %ecx, %edx, because the 39 | // x86 convention is that the caller has saved them. 40 | // Contexts are stored at the bottom of the stack they 41 | // describe; the stack pointer is the address of the context. 42 | // The layout of the context matches the layout of the stack in swtch.S 43 | // at the "Switch stacks" comment. Switch doesn't save eip explicitly, 44 | // but it is on the stack and allocproc() manipulates it. 45 | struct context { 46 | uint r4; 47 | uint r5; 48 | uint r6; 49 | uint r7; 50 | uint r8; 51 | uint r9; 52 | uint r10; 53 | uint r11; 54 | uint r12; 55 | uint lr; 56 | uint pc; 57 | }; 58 | 59 | enum procstate { UNUSED=0, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; 60 | 61 | // Per-process state 62 | struct proc { 63 | uint sz; // Size of process memory (bytes) 64 | pde_t* pgdir; // Page table 65 | char *kstack; // Bottom of kernel stack for this process 66 | enum procstate state; // Process state 67 | volatile int pid; // Process ID 68 | struct proc *parent; // Parent process 69 | struct trapframe *tf; // Trap frame for current syscall 70 | struct context *context; // swtch() here to run process 71 | void *chan; // If non-zero, sleeping on chan 72 | int killed; // If non-zero, have been killed 73 | struct file *ofile[NOFILE]; // Open files 74 | struct inode *cwd; // Current directory 75 | char name[16]; // Process name (debugging) 76 | }; 77 | 78 | // Process memory is laid out contiguously, low addresses first: 79 | // text 80 | // original data and bss 81 | // fixed-size stack 82 | // expandable heap 83 | -------------------------------------------------------------------------------- /uprogs/rm.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | 5 | int 6 | main(int argc, char *argv[]) 7 | { 8 | int i; 9 | 10 | if(argc < 2){ 11 | printf(2, "Usage: rm files...\n"); 12 | exit(); 13 | } 14 | 15 | for(i = 1; i < argc; i++){ 16 | if(unlink(argv[i]) < 0){ 17 | printf(2, "rm: %s failed to delete\n", argv[i]); 18 | break; 19 | } 20 | } 21 | 22 | exit(); 23 | } 24 | -------------------------------------------------------------------------------- /uprogs/spinlock.h: -------------------------------------------------------------------------------- 1 | // Mutual exclusion lock. 2 | struct spinlock { 3 | uint locked; // Is the lock held? 4 | 5 | // For debugging: 6 | char *name; // Name of lock. 7 | struct cpu *cpu; // The cpu holding the lock. 8 | uint pcs[10]; // The call stack (an array of program counters) 9 | // that locked the lock. 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /uprogs/stat.h: -------------------------------------------------------------------------------- 1 | #define T_DIR 1 // Directory 2 | #define T_FILE 2 // File 3 | #define T_DEV 3 // Device 4 | 5 | struct stat { 6 | short type; // Type of file 7 | int dev; // File system's disk device 8 | uint ino; // Inode number 9 | short nlink; // Number of links to file 10 | uint size; // Size of file in bytes 11 | }; 12 | -------------------------------------------------------------------------------- /uprogs/stressfs.c: -------------------------------------------------------------------------------- 1 | // Demonstrate that moving the "acquire" in iderw after the loop that 2 | // appends to the idequeue results in a race. 3 | 4 | // For this to work, you should also add a spin within iderw's 5 | // idequeue traversal loop. Adding the following demonstrated a panic 6 | // after about 5 runs of stressfs in QEMU on a 2.1GHz CPU: 7 | // for (i = 0; i < 40000; i++) 8 | // asm volatile(""); 9 | 10 | #include "types.h" 11 | #include "stat.h" 12 | #include "user.h" 13 | #include "fs.h" 14 | #include "fcntl.h" 15 | 16 | int 17 | main(int argc, char *argv[]) 18 | { 19 | int fd, i; 20 | char path[] = "stressfs0"; 21 | char data[512]; 22 | 23 | printf(1, "stressfs starting\n"); 24 | memset(data, 'a', sizeof(data)); 25 | 26 | for(i = 0; i < 4; i++) 27 | if(fork() > 0) 28 | break; 29 | 30 | printf(1, "write %d\n", i); 31 | 32 | path[8] += i; 33 | fd = open(path, O_CREATE | O_RDWR); 34 | for(i = 0; i < 20; i++) 35 | // printf(fd, "%d\n", i); 36 | write(fd, data, sizeof(data)); 37 | close(fd); 38 | 39 | printf(1, "read\n"); 40 | 41 | fd = open(path, O_RDONLY); 42 | for (i = 0; i < 20; i++) 43 | read(fd, data, sizeof(data)); 44 | close(fd); 45 | 46 | wait(); 47 | 48 | exit(); 49 | } 50 | -------------------------------------------------------------------------------- /uprogs/syscall.h: -------------------------------------------------------------------------------- 1 | // System call numbers 2 | #define SYS_fork 1 3 | #define SYS_exit 2 4 | #define SYS_wait 3 5 | #define SYS_pipe 4 6 | #define SYS_read 5 7 | #define SYS_kill 6 8 | #define SYS_exec 7 9 | #define SYS_fstat 8 10 | #define SYS_chdir 9 11 | #define SYS_dup 10 12 | #define SYS_getpid 11 13 | #define SYS_sbrk 12 14 | #define SYS_sleep 13 15 | #define SYS_uptime 14 16 | #define SYS_open 15 17 | #define SYS_write 16 18 | #define SYS_mknod 17 19 | #define SYS_unlink 18 20 | #define SYS_link 19 21 | #define SYS_mkdir 20 22 | #define SYS_close 21 23 | #define SYS_time 22 24 | -------------------------------------------------------------------------------- /uprogs/timetest.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | 5 | 6 | int main(int argc, char *argv[]) { 7 | int stime = time(); 8 | printf(1, "time is %d\n", stime); 9 | stime = time(); 10 | printf(1, "time is %d\n", stime); 11 | while (time() - 2000000 < stime) { 12 | 13 | } 14 | printf(1, "time is %d\n", time()); 15 | printf(1, "two seconds should have passed\n"); 16 | exit(); 17 | } 18 | -------------------------------------------------------------------------------- /uprogs/traps.h: -------------------------------------------------------------------------------- 1 | // These are arbitrarily chosen, but with care not to overlap 2 | // processor defined exceptions or interrupt vectors. 3 | #define T_SYSCALL 64 // system call 4 | #define T_DEFAULT 500 // catchall 5 | 6 | #define T_IRQ0 32 // IRQ 0 corresponds to int T_IRQ 7 | 8 | #define IRQ_TIMER 0 9 | #define IRQ_KBD 1 10 | #define IRQ_COM1 4 11 | #define IRQ_IDE 14 12 | #define IRQ_ERROR 19 13 | #define IRQ_SPURIOUS 31 14 | 15 | 16 | -------------------------------------------------------------------------------- /uprogs/types.h: -------------------------------------------------------------------------------- 1 | typedef unsigned int u32; 2 | typedef unsigned short u16; 3 | typedef unsigned char u8; 4 | typedef unsigned long long u64; 5 | 6 | typedef unsigned int uint; 7 | typedef unsigned short ushort; 8 | typedef unsigned char uchar; 9 | typedef uint pde_t; 10 | typedef uint pte_t; 11 | 12 | 13 | /* trap vectors layout at virtual 14 | address HVECTORS (and KZERO(0x80000000), doubled mapped).*/ 15 | typedef struct Vpage0 { 16 | void (*vectors[8])(void); 17 | u32 vtable[8]; 18 | } Vpage0; 19 | 20 | 21 | /* interrupt control registers */ 22 | typedef struct Intregs { 23 | u32 ARMpending; 24 | u32 GPUpending[2]; 25 | u32 FIQctl; 26 | u32 GPUenable[2]; 27 | u32 ARMenable; 28 | u32 GPUdisable[2]; 29 | u32 ARMdisable; 30 | } Intregs; 31 | 32 | 33 | typedef struct Mach 34 | { 35 | int machno; /* physical id of processor */ 36 | 37 | int flushmmu; /* flush current proc mmu state */ 38 | 39 | /* stats */ 40 | int tlbfault; 41 | int tlbpurge; 42 | int pfault; 43 | int cs; 44 | int syscall; 45 | int load; 46 | int intr; 47 | int lastintr; 48 | int ilockdepth; 49 | 50 | 51 | int cpumhz; 52 | /* vfp2 or vfp3 fpu */ 53 | int havefp; 54 | int havefpvalid; 55 | int fpon; 56 | int fpconfiged; 57 | int fpnregs; 58 | int fppid; /* pid of last fault */ 59 | int fpcnt; /* how many consecutive at that addr */ 60 | 61 | /* save areas for exceptions, hold R0-R4 */ 62 | u32 sfiq[5]; 63 | u32 sirq[5]; 64 | u32 sund[5]; 65 | u32 sabt[5]; 66 | u32 smon[5]; /* probably not needed */ 67 | u32 ssys[5]; 68 | 69 | int stack[1]; 70 | } Mach; 71 | 72 | 73 | struct framebufferdescription { 74 | u32 width; //width 75 | u32 height; // height 76 | u32 v_width; // virtual width 77 | u32 v_height; // virtual height 78 | u32 pitch; // GPU pitch 79 | u32 depth; // bit depth 80 | u32 x; 81 | u32 y; 82 | u32 fbp; //GPU framebuffer pointer 83 | u32 fbs; // GPU framebuffer size 84 | }; 85 | 86 | typedef struct framebufferdescription FBI; 87 | -------------------------------------------------------------------------------- /uprogs/ulib.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "fcntl.h" 4 | #include "user.h" 5 | #include "arm.h" 6 | 7 | char* 8 | strcpy(char *s, char *t) 9 | { 10 | char *os; 11 | 12 | os = s; 13 | while((*s++ = *t++) != 0) 14 | ; 15 | return os; 16 | } 17 | 18 | int 19 | strcmp(const char *p, const char *q) 20 | { 21 | while(*p && *p == *q) 22 | p++, q++; 23 | return (uchar)*p - (uchar)*q; 24 | } 25 | 26 | uint 27 | strlen(char *s) 28 | { 29 | int n; 30 | 31 | for(n = 0; s[n]; n++) 32 | ; 33 | return n; 34 | } 35 | 36 | void* 37 | memset(void *dst, int c, uint n) 38 | { 39 | char *p=dst; 40 | u32 rc=n; 41 | 42 | while (rc-- > 0) *p++ = c; 43 | return (void *)p; 44 | } 45 | 46 | char* 47 | strchr(const char *s, char c) 48 | { 49 | for(; *s; s++) 50 | if(*s == c) 51 | return (char*)s; 52 | return 0; 53 | } 54 | 55 | char* 56 | gets(char *buf, int max) 57 | { 58 | int i, cc; 59 | char c; 60 | 61 | for(i=0; i+1 < max; ){ 62 | cc = read(0, &c, 1); 63 | if(cc < 1) 64 | break; 65 | buf[i++] = c; 66 | if(c == '\n' || c == '\r') 67 | break; 68 | } 69 | buf[i] = '\0'; 70 | return buf; 71 | } 72 | 73 | int 74 | stat(char *n, struct stat *st) 75 | { 76 | int fd; 77 | int r; 78 | 79 | fd = open(n, O_RDONLY); 80 | if(fd < 0) 81 | return -1; 82 | r = fstat(fd, st); 83 | close(fd); 84 | return r; 85 | } 86 | 87 | int 88 | atoi(const char *s) 89 | { 90 | int n; 91 | 92 | n = 0; 93 | while('0' <= *s && *s <= '9') 94 | n = n*10 + *s++ - '0'; 95 | return n; 96 | } 97 | 98 | void* 99 | memmove(void *vdst, void *vsrc, int n) 100 | { 101 | char *dst, *src; 102 | 103 | dst = vdst; 104 | src = vsrc; 105 | while(n-- > 0) 106 | *dst++ = *src++; 107 | return vdst; 108 | } 109 | -------------------------------------------------------------------------------- /uprogs/umalloc.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | #include "param.h" 5 | 6 | // Memory allocator by Kernighan and Ritchie, 7 | // The C programming Language, 2nd ed. Section 8.7. 8 | 9 | typedef long Align; 10 | 11 | union header { 12 | struct { 13 | union header *ptr; 14 | uint size; 15 | } s; 16 | Align x; 17 | }; 18 | 19 | typedef union header Header; 20 | 21 | static Header base; 22 | static Header *freep; 23 | 24 | void 25 | free(void *ap) 26 | { 27 | Header *bp, *p; 28 | 29 | bp = (Header*)ap - 1; 30 | for(p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) 31 | if(p >= p->s.ptr && (bp > p || bp < p->s.ptr)) 32 | break; 33 | if(bp + bp->s.size == p->s.ptr){ 34 | bp->s.size += p->s.ptr->s.size; 35 | bp->s.ptr = p->s.ptr->s.ptr; 36 | } else 37 | bp->s.ptr = p->s.ptr; 38 | if(p + p->s.size == bp){ 39 | p->s.size += bp->s.size; 40 | p->s.ptr = bp->s.ptr; 41 | } else 42 | p->s.ptr = bp; 43 | freep = p; 44 | } 45 | 46 | static Header* 47 | morecore(uint nu) 48 | { 49 | char *p; 50 | Header *hp; 51 | 52 | if(nu < 4096) 53 | nu = 4096; 54 | p = sbrk(nu * sizeof(Header)); 55 | if(p == (char*)-1) 56 | return 0; 57 | hp = (Header*)p; 58 | hp->s.size = nu; 59 | free((void*)(hp + 1)); 60 | return freep; 61 | } 62 | 63 | void* 64 | malloc(uint nbytes) 65 | { 66 | Header *p, *prevp; 67 | uint nunits; 68 | 69 | nunits = (nbytes + sizeof(Header) - 1)/sizeof(Header) + 1; 70 | if((prevp = freep) == 0){ 71 | base.s.ptr = freep = prevp = &base; 72 | base.s.size = 0; 73 | } 74 | for(p = prevp->s.ptr; ; prevp = p, p = p->s.ptr){ 75 | if(p->s.size >= nunits){ 76 | if(p->s.size == nunits) 77 | prevp->s.ptr = p->s.ptr; 78 | else { 79 | p->s.size -= nunits; 80 | p += p->s.size; 81 | p->s.size = nunits; 82 | } 83 | freep = prevp; 84 | return (void*)(p + 1); 85 | } 86 | if(p == freep) 87 | if((p = morecore(nunits)) == 0) 88 | return 0; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /uprogs/user.h: -------------------------------------------------------------------------------- 1 | struct stat; 2 | 3 | // system calls 4 | int fork(void); 5 | int exit(void) __attribute__((noreturn)); 6 | int wait(void); 7 | int pipe(int*); 8 | int write(int, void*, int); 9 | int read(int, void*, int); 10 | int close(int); 11 | int kill(int); 12 | int exec(char*, char**); 13 | int open(char*, int); 14 | int mknod(char*, short, short); 15 | int unlink(char*); 16 | int fstat(int fd, struct stat*); 17 | int link(char*, char*); 18 | int mkdir(char*); 19 | int chdir(char*); 20 | int dup(int); 21 | int getpid(void); 22 | char* sbrk(int); 23 | int sleep(int); 24 | int uptime(void); 25 | int time(void); 26 | 27 | // ulib.c 28 | int stat(char*, struct stat*); 29 | char* strcpy(char*, char*); 30 | void *memmove(void*, void*, int); 31 | char* strchr(const char*, char c); 32 | int strcmp(const char*, const char*); 33 | void printf(int, char*, ...); 34 | char* gets(char*, int max); 35 | uint strlen(char*); 36 | void* memset(void*, int, uint); 37 | void* malloc(uint); 38 | void free(void*); 39 | int atoi(const char*); 40 | -------------------------------------------------------------------------------- /uprogs/wc.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "stat.h" 3 | #include "user.h" 4 | 5 | char buf[512]; 6 | 7 | void 8 | wc(int fd, char *name) 9 | { 10 | int i, n; 11 | int l, w, c, inword; 12 | 13 | l = w = c = 0; 14 | inword = 0; 15 | while((n = read(fd, buf, sizeof(buf))) > 0){ 16 | for(i=0; i 0){ 12 | sleep(5); // Let child exit before parent. 13 | printf(2, "Parent exits!\n"); 14 | exit(); 15 | } 16 | printf(2, "Child exits!\n"); 17 | exit(); 18 | } 19 | -------------------------------------------------------------------------------- /xv6-guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patha454/xv6_pi_mp/32c5f7678e67a3398e0e9ef544726eecb774a647/xv6-guide.pdf --------------------------------------------------------------------------------