From bb84f09914ecd459d96ed688f39329853fe91bbc Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Mon, 13 Mar 2017 16:22:39 +0000 Subject: [PATCH] Initial Commit --- .gitignore | 72 +++++++++++++++++++++++++ Makefile | 54 +++++++++++++++++++ Makefile.console | 9 ++++ Makefile.disk | 18 +++++++ device/GIC.c | 10 ++++ device/GIC.h | 114 +++++++++++++++++++++++++++++++++++++++ device/MMU.h | 24 +++++++++ device/MMU.s | 63 ++++++++++++++++++++++ device/PL011.c | 67 +++++++++++++++++++++++ device/PL011.h | 89 ++++++++++++++++++++++++++++++ device/PL050.c | 18 +++++++ device/PL050.h | 55 +++++++++++++++++++ device/PL111.c | 3 ++ device/PL111.h | 80 +++++++++++++++++++++++++++ device/SP804.c | 6 +++ device/SP804.h | 71 ++++++++++++++++++++++++ device/SYS.c | 6 +++ device/SYS.h | 103 +++++++++++++++++++++++++++++++++++ device/disk.c | 114 +++++++++++++++++++++++++++++++++++++++ device/disk.h | 36 +++++++++++++ device/disk.py | 138 +++++++++++++++++++++++++++++++++++++++++++++++ image.ld | 18 +++++++ kernel/hilevel.c | 13 +++++ kernel/hilevel.h | 15 ++++++ kernel/int.h | 20 +++++++ kernel/int.s | 69 ++++++++++++++++++++++++ kernel/lolevel.h | 4 ++ kernel/lolevel.s | 34 ++++++++++++ question.pdf | Bin 0 -> 140249 bytes user/P3.c | 30 +++++++++++ user/P3.h | 10 ++++ user/P4.c | 30 +++++++++++ user/P4.h | 10 ++++ user/P5.c | 26 +++++++++ user/P5.h | 10 ++++ user/console.c | 83 ++++++++++++++++++++++++++++ user/console.h | 14 +++++ user/libc.c | 131 ++++++++++++++++++++++++++++++++++++++++++++ user/libc.h | 67 +++++++++++++++++++++++ 39 files changed, 1734 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 Makefile.console create mode 100644 Makefile.disk create mode 100644 device/GIC.c create mode 100644 device/GIC.h create mode 100644 device/MMU.h create mode 100644 device/MMU.s create mode 100644 device/PL011.c create mode 100644 device/PL011.h create mode 100644 device/PL050.c create mode 100644 device/PL050.h create mode 100644 device/PL111.c create mode 100644 device/PL111.h create mode 100644 device/SP804.c create mode 100644 device/SP804.h create mode 100644 device/SYS.c create mode 100644 device/SYS.h create mode 100644 device/disk.c create mode 100644 device/disk.h create mode 100644 device/disk.py create mode 100644 image.ld create mode 100644 kernel/hilevel.c create mode 100644 kernel/hilevel.h create mode 100644 kernel/int.h create mode 100644 kernel/int.s create mode 100644 kernel/lolevel.h create mode 100644 kernel/lolevel.s create mode 100644 question.pdf create mode 100644 user/P3.c create mode 100644 user/P3.h create mode 100644 user/P4.c create mode 100644 user/P4.h create mode 100644 user/P5.c create mode 100644 user/P5.h create mode 100644 user/console.c create mode 100644 user/console.h create mode 100644 user/libc.c create mode 100644 user/libc.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82f4c25 --- /dev/null +++ b/.gitignore @@ -0,0 +1,72 @@ + +# Created by https://www.gitignore.io/api/linux,c + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# End of https://www.gitignore.io/api/linux,c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7c1c1f4 --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +# part 1: variables + + PROJECT_PATH = $(shell find . -mindepth 1 -maxdepth 1 -type d) + PROJECT_SOURCES = $(shell find ${PROJECT_PATH} -name *.c -o -name *.s) + PROJECT_HEADERS = $(shell find ${PROJECT_PATH} -name *.h ) + PROJECT_OBJECTS = $(addsuffix .o, $(basename ${PROJECT_SOURCES})) + PROJECT_TARGETS = image.elf image.bin + + QEMU_PATH = /usr + QEMU_GDB = 127.0.0.1:1234 + QEMU_UART = stdio +#QEMU_UART += telnet:127.0.0.1:1235,server +#QEMU_UART += telnet:127.0.0.1:1236,server + QEMU_DISPLAY = -nographic -display none +#QEMU_DISPLAY = -display sdl + + LINARO_PATH = /usr/local/gcc-linaro-5.1-2015.08-x86_64_arm-eabi + LINARO_PREFIX = arm-eabi + +# part 2: build commands + +%.o : %.s + @${LINARO_PATH}/bin/${LINARO_PREFIX}-as $(addprefix -I , ${PROJECT_PATH} ${LINARO_PATH}/arm-eabi/libc/usr/include) -mcpu=cortex-a8 -g -o ${@} ${<} +%.o : %.c + @${LINARO_PATH}/bin/${LINARO_PREFIX}-gcc $(addprefix -I , ${PROJECT_PATH} ${LINARO_PATH}/arm-eabi/libc/usr/include) -mcpu=cortex-a8 -mabi=aapcs -ffreestanding -std=gnu99 -g -c -O -o ${@} ${<} + +%.elf : ${PROJECT_OBJECTS} + @${LINARO_PATH}/bin/${LINARO_PREFIX}-ld $(addprefix -L , ${LINARO_PATH}/arm-eabi/libc/usr/lib ) -T ${*}.ld -o ${@} ${^} -lc -lgcc +%.bin : %.elf + @${LINARO_PATH}/bin/${LINARO_PREFIX}-objcopy -O binary ${<} ${@} + +# part 3: targets + +.PRECIOUS : ${PROJECT_OBJECTS} ${PROJECT_TARGETS} + +build : ${PROJECT_TARGETS} + +launch-qemu : ${PROJECT_TARGETS} + @${QEMU_PATH}/bin/qemu-system-arm -M realview-pb-a8 -m 128M ${QEMU_DISPLAY} -gdb tcp:${QEMU_GDB} $(addprefix -serial , ${QEMU_UART}) -S -kernel $(filter %.bin, ${PROJECT_TARGETS}) + +launch-gdb : ${PROJECT_TARGETS} + @${LINARO_PATH}/bin/${LINARO_PREFIX}-gdb -ex "file $(filter %.elf, ${PROJECT_TARGETS})" -ex "target remote ${QEMU_GDB}" + +kill-qemu : + @-killall --quiet --user ${USER} qemu-system-arm + +kill-gdb : + @-killall --quiet --user ${USER} ${LINARO_PREFIX}-gdb + +clean : + @rm -f core ${PROJECT_OBJECTS} ${PROJECT_TARGETS} + +include Makefile.console +include Makefile.disk diff --git a/Makefile.console b/Makefile.console new file mode 100644 index 0000000..0564c08 --- /dev/null +++ b/Makefile.console @@ -0,0 +1,9 @@ +# part 1: variables + + CONSOLE_HOST = 127.0.0.1 + CONSOLE_PORT = 1235 + +# part 3: targets + +launch-console : + @nc ${CONSOLE_HOST} ${CONSOLE_PORT} diff --git a/Makefile.disk b/Makefile.disk new file mode 100644 index 0000000..2fbfe73 --- /dev/null +++ b/Makefile.disk @@ -0,0 +1,18 @@ +# part 1: variables + + DISK_FILE = disk.bin + DISK_HOST = 127.0.0.1 + DISK_PORT = 1236 + DISK_BLOCK_NUM = 65536 + DISK_BLOCK_LEN = 16 + +# part 3: targets + + create-disk : + @dd of=${DISK_FILE} if=/dev/zero count=${DISK_BLOCK_NUM} bs=${DISK_BLOCK_LEN} + +inspect-disk : + @hexdump -C ${DISK_FILE} + + launch-disk : + @python device/disk.py --host=${DISK_HOST} --port=${DISK_PORT} --file=${DISK_FILE} --block-num=${DISK_BLOCK_NUM} --block-len=${DISK_BLOCK_LEN} diff --git a/device/GIC.c b/device/GIC.c new file mode 100644 index 0000000..2ea5aab --- /dev/null +++ b/device/GIC.c @@ -0,0 +1,10 @@ +#include "GIC.h" + +volatile GICC_t* GICC0 = ( volatile GICC_t* )( 0x1E000000 ); +volatile GICD_t* GICD0 = ( volatile GICD_t* )( 0x1E001000 ); +volatile GICC_t* GICC1 = ( volatile GICC_t* )( 0x1E010000 ); +volatile GICD_t* GICD1 = ( volatile GICD_t* )( 0x1E011000 ); +volatile GICC_t* GICC2 = ( volatile GICC_t* )( 0x1E020000 ); +volatile GICD_t* GICD2 = ( volatile GICD_t* )( 0x1E021000 ); +volatile GICC_t* GICC3 = ( volatile GICC_t* )( 0x1E030000 ); +volatile GICD_t* GICD3 = ( volatile GICD_t* )( 0x1E031000 ); diff --git a/device/GIC.h b/device/GIC.h new file mode 100644 index 0000000..169afe9 --- /dev/null +++ b/device/GIC.h @@ -0,0 +1,114 @@ +#ifndef __GIC_H +#define __GIC_H + +#include +#include +#include + +#define RSVD(x,y,z) uint8_t reserved##x[ z - y + 1 ]; + +/* Although the GIC architecture is documented at + * + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html + * + * the platform includes a bespoke implementation based on the combination + * of 4 GIC components in total. + * + * - Section 3.14 gives a high-level overview of the interrupt mechanism, + * noting in particular that GIC0 and GIC1 are those associated with the + * ARM core (managing IRQ- and FIQ-based interrupts respectively), + * - Section 4.11 describes the GIC implementation, which sub-divides each + * GIC into interface and distributor components: it includes + * + * - Table 4.44, i.e., the mapping of interrupt signals from + * other devices to interrupt IDs wrt. each GIC, + * - Tables 4.46 and 4.55, i.e., the device register layout (including + * an offset from the device base address, in the memory map, for each + * register), plus + * - a summary of the internal structure of each device register. + * + * Note that the field identifiers used here follow the documentation in a + * general sense, but with a some minor alterations to improve clarity and + * consistency. + */ + +typedef volatile struct { + uint32_t CTLR; // 0x0000 : control + uint32_t PMR; // 0x0004 : priority mask + uint32_t BPR; // 0x0008 : binary point + uint32_t IAR; // 0x000C : interrupt acknowledge + uint32_t EOIR; // 0x0010 : end of interrupt + uint32_t RPR; // 0x0014 : running interrupt + uint32_t HPPIR; // 0x0018 : highest pending interrupt +} GICC_t; + +typedef volatile struct { + uint32_t CTLR; // 0x0000 : control + uint32_t TYPER; // 0x0004 : controller type + RSVD( 0, 0x0008, 0x00FC ); // 0x0008...0x00FC : reserved + uint32_t ISENABLER0; // 0x0100 : set-enable + uint32_t ISENABLER1; // 0x0104 : set-enable + uint32_t ISENABLER2; // 0x0108 : set-enable + RSVD( 1, 0x010C, 0x017C ); // 0x010C...0x017C : reserved + uint32_t ICENABLER0; // 0x0180 : clear-enable + uint32_t ICENABLER1; // 0x0184 : clear-enable + uint32_t ICENABLER2; // 0x0188 : clear-enable + RSVD( 2, 0x018C, 0x01FC ); // 0x018C...0x01FC : reserved + uint32_t ISPENDR0; // 0x0200 : set-pending + uint32_t ISPENDR1; // 0x0204 : set-pending + uint32_t ISPENDR2; // 0x0208 : set-pending + RSVD( 3, 0x020C, 0x027C ); // 0x020C...0x027C : reserved + uint32_t ICPENDR0; // 0x0280 : clear-pending + uint32_t ICPENDR1; // 0x0284 : clear-pending + uint32_t ICPENDR2; // 0x0288 : clear-pending + RSVD( 4, 0x028C, 0x02FC ); // 0x028C...0x02FC : reserved + uint32_t ISACTIVER0; // 0x0300 : set-active + uint32_t ISACTIVER1; // 0x0304 : set-active + uint32_t ISACTIVER2; // 0x0308 : set-active + RSVD( 5, 0x030C, 0x03FC ); // 0x030C...0x03FC : reserved + uint32_t IPRIORITYR[ 24 ]; // 0x0400...0x045C : priority + RSVD( 6, 0x0460, 0x07FC ); // 0x0460...0x07FC : reserved + uint32_t ITARGETSR[ 24 ]; // 0x0800...0x085C : processor target + RSVD( 7, 0x0860, 0x0BFC ); // 0x0760...0x0BFC : reserved + uint32_t ICFGR0; // 0x0C00 : configuration + uint32_t ICFGR1; // 0x0C04 : configuration + uint32_t ICFGR2; // 0x0C08 : configuration + uint32_t ICFGR3; // 0x0C0C : configuration + uint32_t ICFGR4; // 0x0C10 : configuration + uint32_t ICFGR5; // 0x0C14 : configuration + RSVD( 8, 0x0C18, 0x0EFC ); // 0x0C18...0x0EFC : reserved + uint32_t SGIR; // 0x0F00 : software interrupt + RSVD( 9, 0x0F04, 0x0FFC ); // 0x0F04...0x0FFC : reserved +} GICD_t; + +#define GIC_SOURCE_TIMER0 ( 36 ) +#define GIC_SOURCE_TIMER1 ( 37 ) +#define GIC_SOURCE_TIMER2 ( 73 ) +#define GIC_SOURCE_TIMER3 ( 74 ) + +#define GIC_SOURCE_UART0 ( 44 ) +#define GIC_SOURCE_UART1 ( 45 ) +#define GIC_SOURCE_UART2 ( 46 ) +#define GIC_SOURCE_UART3 ( 47 ) + +#define GIC_SOURCE_PS20 ( 52 ) +#define GIC_SOURCE_PS21 ( 53 ) + +/* Per Table 4.2 (for example: the information is in several places) of + * + * http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/index.html + * + * we know the registers are mapped to fixed addresses in memory, so we + * can just define a (structured) pointer to each one to support access. + */ + +extern volatile GICC_t* GICC0; +extern volatile GICD_t* GICD0; +extern volatile GICC_t* GICC1; +extern volatile GICD_t* GICD1; +extern volatile GICC_t* GICC2; +extern volatile GICD_t* GICD2; +extern volatile GICC_t* GICC3; +extern volatile GICD_t* GICD3; + +#endif diff --git a/device/MMU.h b/device/MMU.h new file mode 100644 index 0000000..b39d85c --- /dev/null +++ b/device/MMU.h @@ -0,0 +1,24 @@ +#ifndef __MMU_H +#define __MMU_H + +#include +#include +#include + +// enable MMU +void mmu_enable(); +// disable MMU +void mmu_unable(); + +// flush TLB +void mmu_flush(); + +// configure MMU: set page table pointer #0 to x +void mmu_set_ptr0( uint32_t* x ); +// configure MMU: set page table pointer #1 to x +void mmu_set_ptr1( uint32_t* x ); + +// configure MMU: set 2-bit permission field of domain d to x +void mmu_set_dom( int d, uint8_t x ); + +#endif diff --git a/device/MMU.s b/device/MMU.s new file mode 100644 index 0000000..c67e10f --- /dev/null +++ b/device/MMU.s @@ -0,0 +1,63 @@ +@ Section B3.17 of +@ +@ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c/index.html +@ +@ gives a (fairly) concise overview of co-processor 15, which is used +@ to control the MMU. It takes some effort to decipher, but, as an +@ example, Figure B3-29 says that if we use an mcr instruction +@ +@ id = p15, opc1 = 0, CRn = c2, CRm = c0, opc2 = 0 +@ +@ then we are writing into the TTBR0 register, i.e., the first page +@ table pointer register. Clearly doing so requires very low-level +@ attention to detail that could and perhaps should be abstracted +@ via a higher-level API: the following functions do that, albeit +@ for an *extremely* limited sub-set of functionality wrt. the MMU. + +.global mmu_enable +.global mmu_unable + +.global mmu_flush + +.global mmu_set_ptr0 +.global mmu_set_ptr1 + +.global mmu_set_dom + +mmu_enable: mrc p15, 0, r0, c1, c0, 0 @ read SCTLR + orr r0, r0, #0x1 @ set SCTLR[ M ] = 1 => MMU enable + mcr p15, 0, r0, c1, c0, 0 @ write SCTLR + + mov pc, lr @ return + +mmu_unable: mrc p15, 0, r0, c1, c0, 0 @ read SCTLR + bic r0, r0, #0x1 @ set SCTLR[ M ] = 0 => MMU disable + mcr p15, 0, r0, c1, c0, 0 @ write SCTLR + + mov pc, lr @ return + +mmu_flush: mov r0, #0x0 + mcr p15, 0, r0, c8, c7, 0 @ write TLBIALL + + mov pc, lr @ return + +mmu_set_ptr0: mcr p15, 0, r0, c2, c0, 0 @ write TTBR0 + + mov pc, lr @ return + +mmu_set_ptr1: mcr p15, 0, r0, c2, c0, 1 @ write TTBR1 + + mov pc, lr @ return + +mmu_set_dom: add r0, r0, r0 @ compute i (index from domain) + mov r1, r1, lsl r0 @ compute j (permission from domain) + mov r2, #0x3 + mov r2, r2, lsl r0 @ compute m (mask from domain) + + mrc p15, 0, r0, c3, c0, 0 @ read DACR + bic r0, r0, r2 @ mask DACR &= ~m => DACR_{i+1,i} = 0 + orr r0, r0, r1 @ set DACR_{i+1,i} = j + mcr p15, 0, r0, c3, c0, 0 @ write DACR + + mov pc, lr @ return + diff --git a/device/PL011.c b/device/PL011.c new file mode 100644 index 0000000..e9744c8 --- /dev/null +++ b/device/PL011.c @@ -0,0 +1,67 @@ +#include "PL011.h" + +volatile PL011_t* UART0 = ( volatile PL011_t* )( 0x10009000 ); +volatile PL011_t* UART1 = ( volatile PL011_t* )( 0x1000A000 ); +volatile PL011_t* UART2 = ( volatile PL011_t* )( 0x1000B000 ); +volatile PL011_t* UART3 = ( volatile PL011_t* )( 0x1000C000 ); + +int xtoi( char x ) { + if ( ( x >= '0' ) && ( x <= '9' ) ) { + return ( 0 + ( x - '0' ) ); + } + else if ( ( x >= 'a' ) && ( x <= 'f' ) ) { + return ( 10 + ( x - 'a' ) ); + } + else if ( ( x >= 'A' ) && ( x <= 'F' ) ) { + return ( 10 + ( x - 'A' ) ); + } + + return -1; +} + +char itox( int x ) { + if ( ( x >= 0 ) && ( x <= 9 ) ) { + return '0' + ( x - 0 ); + } + else if( ( x >= 10 ) && ( x <= 15 ) ) { + return 'A' + ( x - 10 ); + } + + return -1; +} + +bool PL011_can_putc( PL011_t* d ) { + // can putc iff. transmit FIFO is not full + return !( d->FR & 0x20 ); +} + +bool PL011_can_getc( PL011_t* d ) { + // can getc iff. receive FIFO is not empty + return !( d->FR & 0x10 ); +} + +void PL011_putc( PL011_t* d, uint8_t x, bool f ) { + // wait while blocking enabled and transmit FIFO is full + while( f && ( d->FR & 0x20 ) ); + // transmit x + d->DR = x; +} + +uint8_t PL011_getc( PL011_t* d, bool f ) { + // wait while blocking enabled and receive FIFO is empty + while( f && ( d->FR & 0x10 ) ); + // recieve r + return d->DR; +} + +void PL011_puth( PL011_t* d, uint8_t x, bool f ) { + PL011_putc( d, itox( ( x >> 4 ) & 0xF ), f ); + PL011_putc( d, itox( ( x >> 0 ) & 0xF ), f ); +} + +uint8_t PL011_geth( PL011_t* d, bool f ) { + uint8_t r = ( xtoi( PL011_getc( d, f ) ) << 4 ); + r |= ( xtoi( PL011_getc( d, f ) ) << 0 ); + + return r; +} diff --git a/device/PL011.h b/device/PL011.h new file mode 100644 index 0000000..b0dd6f9 --- /dev/null +++ b/device/PL011.h @@ -0,0 +1,89 @@ +#ifndef __PL011_H +#define __PL011_H + +#include +#include +#include + +#define RSVD(x,y,z) uint8_t reserved##x[ z - y + 1 ]; + +/* The ARM PrimeCell UART (PL011) is documented at + * + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183g/index.html + * + * In particular, Section 3 explains the programmer's model, i.e., how to + * interact with it: this includes + * + * - Section 3.2, which summarises the device register layout in Table 3.1 + * (including an offset from the device base address, in the memory map, + * for each register), and + * - Section 3.3, which summarises the internal structure of each device + * register. + * + * Note that the field identifiers used here follow the documentation in a + * general sense, but with a some minor alterations to improve clarity and + * consistency. + */ + +typedef volatile struct { + uint32_t DR; // 0x0000 : data + union { uint32_t RSR; // 0x0004 : receive status + uint32_t ECR; }; // | error clear + RSVD( 0, 0x0008, 0x0017 ); // 0x0008...0x0017 : reserved + uint32_t FR; // 0x0018 : flag + RSVD( 1, 0x001C, 0x001F ); // 0x001C...0x001F : reserved + uint32_t LPR; // 0x0020 : low-power counter + uint32_t IBRD; // 0x0024 : integer baud rate + uint32_t FBRD; // 0x0028 : fractional baud rate + uint32_t LCR; // 0x002C : line control + uint32_t CR; // 0x0030 : control + uint32_t IFLS; // 0x0034 : interrupt level select + uint32_t IMSC; // 0x0038 : interrupt mask + uint32_t RIS; // 0x003C : raw interrupt status + uint32_t MIS; // 0x0040 : masked interrupt status + uint32_t ICR; // 0x0044 : interrupt clear + uint32_t DMACR; // 0x0048 : DMA control + RSVD( 2, 0x004C, 0x0FDF ); // 0x004C...0x0FDF : reserved + uint32_t PeriphID0; // 0x0FE0 : peripheral ID + uint32_t PeriphID1; // 0x0FE4 : peripheral ID + uint32_t PeriphID2; // 0x0FE8 : peripheral ID + uint32_t PeriphID3; // 0x0FEC : peripheral ID + uint32_t PCellID0; // 0x0FF0 : PrimeCell ID + uint32_t PCellID1; // 0x0FF4 : PrimeCell ID + uint32_t PCellID2; // 0x0FF8 : PrimeCell ID + uint32_t PCellID3; // 0x0FFC : PrimeCell ID +} PL011_t; + +/* Per Table 4.2 (for example: the information is in several places) of + * + * http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/index.html + * + * we know the registers are mapped to fixed addresses in memory, so we + * can just define a (structured) pointer to each one to support access. + */ + +extern volatile PL011_t* UART0; +extern volatile PL011_t* UART1; +extern volatile PL011_t* UART2; +extern volatile PL011_t* UART3; + +// convert a hexadecimal character x into an integer 0 < r < 16 +extern int xtoi( char x ); +// convert an integer 0 < x < 16 into a hexadecimal character r +extern char itox( int x ); + +// check whether transmitting via PL011 instance d will block +extern bool PL011_can_putc( PL011_t* d ); +// check whether receiving via PL011 instance d will block +extern bool PL011_can_getc( PL011_t* d ); + +// transmit raw byte x via PL011 instance d (blocking iff. f = true) +extern void PL011_putc( PL011_t* d, uint8_t x, bool f ); +// receive raw byte r via PL011 instance d (blocking iff. f = true) +extern uint8_t PL011_getc( PL011_t* d, bool f ); +// transmit hexified byte x via PL011 instance d (blocking iff. f = true) +extern void PL011_puth( PL011_t* d, uint8_t x, bool f ); +// receive hexified byte r via PL011 instance d (blocking iff. f = true) +extern uint8_t PL011_geth( PL011_t* d, bool f ); + +#endif diff --git a/device/PL050.c b/device/PL050.c new file mode 100644 index 0000000..a03333f --- /dev/null +++ b/device/PL050.c @@ -0,0 +1,18 @@ +#include "PL050.h" + +volatile PL050_t* PS20 = ( volatile PL050_t* )( 0x10006000 ); +volatile PL050_t* PS21 = ( volatile PL050_t* )( 0x10007000 ); + +void PL050_putc( PL050_t* d, uint8_t x ) { + // wait while transmit register isn't empty + while( !( d->STAT & 0x40 ) ); + // transmit x + d->DATA = x; +} + +uint8_t PL050_getc( PL050_t* d ) { + // wait while receive register isn't full + while( !( d->STAT & 0x10 ) ); + // recieve r + return d->DATA; +} diff --git a/device/PL050.h b/device/PL050.h new file mode 100644 index 0000000..5304224 --- /dev/null +++ b/device/PL050.h @@ -0,0 +1,55 @@ +#ifndef __PL050_H +#define __PL050_H + +#include +#include +#include + +#define RSVD(x,y,z) uint8_t reserved##x[ z - y + 1 ]; + +/* The ARM PrimeCell PS2 Keyboard/Mouse Interface (PL050) is documented at + * + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0143c/index.html + * + * In particular, Section 3 explains the programmer's model, i.e., how to + * interact with it: this includes + * + * - Section 3.2, which summarises the device register layout in Table 3.1 + * (including an offset from the device base address, in the memory map, + * for each register), and + * - Section 3.3, which summarises the internal structure of each device + * register. + * + * Note that the field identifiers used here follow the documentation in a + * general sense, but with a some minor alterations to improve clarity and + * consistency. + */ + +typedef volatile struct { + uint32_t CR; // 0x0000 : control + uint32_t STAT; // 0x0004 : status + uint32_t DATA; // 0x0008 : data + uint32_t CLKDIV; // 0x000C : clock divisor + uint32_t IR; // 0x0010 : interrupt status + RSVD( 0, 0x0008, 0x0017 ); // 0x0014...0x003C : reserved + RSVD( 1, 0x001C, 0x001F ); // 0x0040...0x009C : reserved + RSVD( 2, 0x004C, 0x0FDF ); // 0x00A0...0x00FF : reserved +} PL050_t; + +/* Per Table 4.2 (for example: the information is in several places) of + * + * http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/index.html + * + * we know the registers are mapped to fixed addresses in memory, so we + * can just define a (structured) pointer to each one to support access. + */ + +extern volatile PL050_t* PS20; // keyboard +extern volatile PL050_t* PS21; // mouse + +// transmit raw byte x via PL050 instance d +extern void PL050_putc( PL050_t* d, uint8_t x ); +// recieve raw byte r via PL050 instance d +extern uint8_t PL050_getc( PL050_t* d ); + +#endif diff --git a/device/PL111.c b/device/PL111.c new file mode 100644 index 0000000..8aeb64d --- /dev/null +++ b/device/PL111.c @@ -0,0 +1,3 @@ +#include "PL111.h" + +volatile PL111_t* LCD = ( volatile PL111_t* )( 0x10020000 ); diff --git a/device/PL111.h b/device/PL111.h new file mode 100644 index 0000000..4523c8b --- /dev/null +++ b/device/PL111.h @@ -0,0 +1,80 @@ +#ifndef __PL111_H +#define __PL111_H + +#include +#include +#include + +#define RSVD(x,y,z) uint8_t reserved##x[ z - y + 1 ]; + +/* The ARM PrimeCell ColorLCD Controller (PL111) is documented at + * + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0293c/index.html + * + * In particular, Section 3 explains the programmer's model, i.e., how to + * interact with it: this includes + * + * - Section 3.2, which summarises the device register layout in Table 3.1 + * (including an offset from the device base address, in the memory map, + * for each register), and + * - Section 3.3, which summarises the internal structure of each device + * register. + * + * Note that the field identifiers used here follow the documentation in a + * general sense, but with a some minor alterations to improve clarity and + * consistency. + */ + +typedef volatile struct { + uint32_t LCDTiming0; // 0x0000 : horizontal axis + uint32_t LCDTiming1; // 0x0004 : vertical axis + uint32_t LCDTiming2; // 0x0008 : clock and signal polarity + uint32_t LCDTiming3; // 0x000C : line end + uint32_t LCDUPBASE; // 0x0010 : upper panel base address + uint32_t LCDLPBASE; // 0x0014 : lower panel base address + uint32_t LCDControl; // 0x0018 : control + uint32_t LCDIMSC; // 0x001C : interrupt mask + uint32_t LCDRIS; // 0x0020 : raw interrupt status + uint32_t LCDMIS; // 0x0024 : masked interrupt status + uint32_t LCDICR; // 0x0028 : interrupt clear + uint32_t LCDUPCURR; // 0x002C : upper panel current address + uint32_t LCDLPCURR; // 0x0030 : lower panel current address + RSVD( 0, 0x0034, 0x01FC ); // 0x0034...0x01FC : reserved + uint16_t LCDPalette[ 256 ]; // 0x0200...0x03FC : color palette + RSVD( 1, 0x0400, 0x07FC ); // 0x0400...0x07FC : reserved + uint32_t ClcdCrsrImage[ 256 ]; // 0x0800...0x0BFC : cursor image + uint32_t ClcdCrsrCtrl; // 0x0C00 : cursor control + uint32_t ClcdCrsrConfig; // 0x0C04 : cursor configuration + uint32_t ClcdCrsrPalette0; // 0x0C08...0x0C0C : cursor palette + uint32_t ClcdCrsrPalette1; // 0x0C08...0x0C0C : cursor palette + uint32_t ClcdCrsrXY; // 0x0C10 : cursor position + uint32_t ClcdCrsrClip; // 0x0C14 : cursor clip position + RSVD( 2, 0x0C18, 0x0C1C ); // 0x0C18...0x0C1C : reserved + uint32_t ClcdCrsrIMSC; // 0x0C20 : cursor interrupt mask + uint32_t ClcdCrsrICR; // 0x0C24 : cursor interrupt clear + uint32_t ClcdCrsrRIS; // 0x0C28 : cursor raw interrupt status + uint32_t ClcdCrsrMIS; // 0x0C2C : cursor masked interrupt status + RSVD( 3, 0x0C30, 0x0DFC ); // 0x0C30...0x0DFC : reserved + RSVD( 4, 0x0F00, 0x0F08 ); // 0x0F00...0x0F08 : reserved + RSVD( 5, 0x0F0C, 0x0FDC ); // 0x0F0C...0x0FDC : reserved + uint32_t PeriphID0; // 0x0FE0 : peripheral ID + uint32_t PeriphID1; // 0x0FE4 : peripheral ID + uint32_t PeriphID2; // 0x0FE8 : peripheral ID + uint32_t PeriphID3; // 0x0FEC : peripheral ID + uint32_t PCellID0; // 0x0FF0 : PrimeCell ID + uint32_t PCellID1; // 0x0FF4 : PrimeCell ID + uint32_t PCellID2; // 0x0FF8 : PrimeCell ID + uint32_t PCellID3; // 0x0FFC : PrimeCell ID +} PL111_t; + +/* Per Table 4.2 (for example: the information is in several places) of + * + * http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/index.html + * + * we know the registers are mapped to fixed addresses in memory, so we + * can just define a (structured) pointer to each one to support access. + */ + +extern volatile PL111_t* LCD; + +#endif diff --git a/device/SP804.c b/device/SP804.c new file mode 100644 index 0000000..aafb3fb --- /dev/null +++ b/device/SP804.c @@ -0,0 +1,6 @@ +#include "SP804.h" + +volatile SP804_t* TIMER0 = ( volatile SP804_t* )( 0x10011000 ); +volatile SP804_t* TIMER1 = ( volatile SP804_t* )( 0x10012000 ); +volatile SP804_t* TIMER2 = ( volatile SP804_t* )( 0x10018000 ); +volatile SP804_t* TIMER3 = ( volatile SP804_t* )( 0x10019000 ); diff --git a/device/SP804.h b/device/SP804.h new file mode 100644 index 0000000..c1d438e --- /dev/null +++ b/device/SP804.h @@ -0,0 +1,71 @@ +#ifndef __SP804_H +#define __SP804_H + +#include +#include +#include + +#define RSVD(x,y,z) uint8_t reserved##x[ z - y + 1 ]; + +/* The ARM Dual-Timer Module (SP804) is documented at + * + * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0271d/index.html + * + * In particular, Section 3 explains the programmer's model, i.e., how to + * interact with it: this includes + * + * - Section 3.2, which summarises the device register layout in Table 3.1 + * (including an offset from the device base address, in the memory map, + * for each register), and + * - Section 3.3, which summarises the internal structure of each device + * register. + * + * Note that the field identifiers used here follow the documentation in a + * general sense, but with a some minor alterations to improve clarity and + * consistency. + */ + +typedef volatile struct { + uint32_t Timer1Load; // 0x0000 : load + uint32_t Timer1Value; // 0x0004 : current value + uint32_t Timer1Ctrl; // 0x0008 : control + uint32_t Timer1IntClr; // 0x000C : interrupt clear + uint32_t Timer1RIS; // 0x0010 : raw interrupt status + uint32_t Timer1MIS; // 0x0014 : masked interrupt status + uint32_t Timer1BGLoad; // 0x0018 : background load + RSVD( 0, 0x001C, 0x001F ); // 0x001C...0x001F : reserved + uint32_t Timer2Load; // 0x0020 : load + uint32_t Timer2Value; // 0x0024 : current value + uint32_t Timer2Ctrl; // 0x0028 : control + uint32_t Timer2IntClr; // 0x002C : interrupt clear + uint32_t Timer2RIS; // 0x0030 : raw interrupt status + uint32_t Timer2MIS; // 0x0034 : masked interrupt status + uint32_t Timer2BGLoad; // 0x0038 : background load + RSVD( 1, 0x003C, 0x0EFF ); // 0x003C...0x0EFF : reserved + uint32_t TimerITCR; // 0x0F00 : integration test + uint32_t TimerITOP; // 0x0F04 : integration test + RSVD( 2, 0x0F08, 0x0FDF ); // 0x0F08...0x0FDF : reserved + uint32_t PeriphID0; // 0x0FE0 : peripheral ID + uint32_t PeriphID1; // 0x0FE4 : peripheral ID + uint32_t PeriphID2; // 0x0FE8 : peripheral ID + uint32_t PeriphID3; // 0x0FEC : peripheral ID + uint32_t PCellID0; // 0x0FF0 : PrimeCell ID + uint32_t PCellID1; // 0x0FF4 : PrimeCell ID + uint32_t PCellID2; // 0x0FF8 : PrimeCell ID + uint32_t PCellID3; // 0x0FFC : PrimeCell ID +} SP804_t; + +/* Per Table 4.2 (for example: the information is in several places) of + * + * http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/index.html + * + * we know the registers are mapped to fixed addresses in memory, so we + * can just define a (structured) pointer to each one to support access. + */ + +extern volatile SP804_t* TIMER0; // timer module 0 -> timers #0 and #1 +extern volatile SP804_t* TIMER1; // timer module 1 -> timers #2 and #3 +extern volatile SP804_t* TIMER2; // timer module 2 -> timers #4 and #5 +extern volatile SP804_t* TIMER3; // timer module 3 -> timers #6 and #7 + +#endif diff --git a/device/SYS.c b/device/SYS.c new file mode 100644 index 0000000..79af14e --- /dev/null +++ b/device/SYS.c @@ -0,0 +1,6 @@ +#include "SYS.h" + +volatile SYSCONF_t* SYSCONF = ( volatile SYSCONF_t* )( 0x10000000 ); + +volatile uint32_t* SYSCTRL0 = ( volatile uint32_t* )( 0x10001000 ); +volatile uint32_t* SYSCTRL1 = ( volatile uint32_t* )( 0x1001A000 ); diff --git a/device/SYS.h b/device/SYS.h new file mode 100644 index 0000000..ae997d9 --- /dev/null +++ b/device/SYS.h @@ -0,0 +1,103 @@ +#ifndef __SYS_H +#define __SYS_H + +#include +#include +#include + +#define RSVD(x,y,z) uint8_t reserved##x[ z - y + 1 ]; + +/* As outlined in Section 4.3 and 4.4, especially Table 4.5, of + * + * http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/index.html + * + * the platform houses various configuration and control registers: these + * allow a) control over and b) inspection of the state maintained by the + * resources and devices it houses; some are rendered moot when placed in + * an emulated context of course. + */ + +typedef volatile struct { + uint32_t ID; // 0x0000 : system identifier + uint32_t USERSW; // 0x0004 : user switch + uint32_t LED; // 0x0008 : user LED + uint32_t OSC0; // 0x000C : oscillator configuration + uint32_t OSC1; // 0x0010 : oscillator configuration + uint32_t OSC2; // 0x0014 : oscillator configuration + uint32_t OSC3; // 0x0018 : oscillator configuration + uint32_t OSC4; // 0x001C : oscillator configuration + uint32_t LOCK; // 0x0020 : lock control + uint32_t COUNTER_100HZ; // 0x0024 : 100Hz counter + RSVD( 0, 0x0028, 0x002C ); // 0x0028...0x002C : reserved + union { uint32_t FLAGS; // 0x0030 : general-purpose flags + uint32_t FLAGSSET; }; // 0x0030 | general-purpose flags set + uint32_t FLAGSCLR; // 0x0034 : general-purpose flags clear + union { uint32_t NVFLAGS; // 0x0038 : general-purpose non-volatile flags + uint32_t NVFLAGSSET; }; // 0x0038 | general-purpose non-volatile flags set + uint32_t NVFLAGSCLR; // 0x003C : general-purpose non-volatile flags clear + uint32_t RESETCTL; // 0x0040 : software reset level + RSVD( 1, 0x0044, 0x0047 ); // 0x0044...0x0047 : reserved + uint32_t MCI; // 0x0048 : MCI status + uint32_t FLASH; // 0x004C : flash write protection + uint32_t CLCD; // 0x0050 : colour LCD power and multiplexing + RSVD( 2, 0x0054, 0x0057 ); // 0x0054...0x0057 : reserved + uint32_t CFGSW; // 0x0058 : user switch configuration + uint32_t COUNTER_24MHZ; // 0x005C : 24MHz counter + uint32_t MISC; // 0x0060 : miscellaneous + uint32_t DMAPSR; // 0x0064 : DMA mapping + uint32_t PEX_STAT; // 0x0068 : PCI Express status + uint32_t PCI_STAT; // 0x006C : PCI status + RSVD( 3, 0x0070, 0x0073 ); // 0x0070...0x0073 : reserved + uint32_t PLD_CTRL1; // 0x0074 : PLD configuration + uint32_t PLD_CTRL2; // 0x0078 : PLD configuration + uint32_t PLL_INIT; // 0x007C : PLL configuration + RSVD( 4, 0x0080, 0x0083 ); // 0x0080...0x0083 : reserved + uint32_t PROCID0; // 0x0084 : processor ID + uint32_t PROCID1; // 0x0088 : processor ID + uint32_t OSCRESET0; // 0x008C : oscillator reset value + uint32_t OSCRESET1; // 0x0090 : oscillator reset value + uint32_t OSCRESET2; // 0x0094 : oscillator reset value + uint32_t OSCRESET3; // 0x0098 : oscillator reset value + uint32_t OSCRESET4; // 0x009A : oscillator reset value + uint32_t VOLTAGE_CTL0; // 0x00A0 : voltate control/monitoring + uint32_t VOLTAGE_CTL1; // 0x00A4 : voltate control/monitoring + uint32_t VOLTAGE_CTL2; // 0x00A8 : voltate control/monitoring + uint32_t VOLTAGE_CTL3; // 0x00AA : voltate control/monitoring + uint32_t VOLTAGE_CTL4; // 0x00AC : voltate control/monitoring + uint32_t VOLTAGE_CTL5; // 0x00B0 : voltate control/monitoring + uint32_t VOLTAGE_CTL6; // 0x00B4 : voltate control/monitoring + uint32_t VOLTAGE_CTL7; // 0x00B8 : voltate control/monitoring + uint32_t VOLTAGE_CTL8; // 0x00BC : voltate control/monitoring + uint32_t TEST_OSC0; // 0x00C0 : oscillator driven counter + uint32_t TEST_OSC1; // 0x00C4 : oscillator driven counter + uint32_t TEST_OSC2; // 0x00C8 : oscillator driven counter + uint32_t TEST_OSC3; // 0x00CC : oscillator driven counter + uint32_t TEST_OSC4; // 0x00D0 : oscillator driven counter + uint32_t OSC5; // 0x00D4 : oscillator configuration + uint32_t OSC6; // 0x00D8 : oscillator configuration + uint32_t OSCRESET5; // 0x00DC : oscillator reset value + uint32_t OSCRESET6; // 0x00E0 : oscillator reset value + uint32_t TEST_OSC5; // 0x00E4 : oscillator driven counter + uint32_t TEST_OSC6; // 0x00E8 : oscillator driven counter + uint32_t OSC7; // 0x00EC : oscillator configuration + uint32_t OSCRESET7; // 0x00F0 : oscillator reset value + uint32_t TEST_OSC7; // 0x00F4 : oscillator driven counter + uint32_t DEBUG; // 0x00F8 : debug unit configuration + uint32_t TESTMODE; // 0x00FC : test mode configuration + uint32_t PLL_RESET; // 0x0100 : PLL reset value +} SYSCONF_t; + +/* Per Table 4.2 (for example: the information is in several places) of + * + * http://infocenter.arm.com/help/topic/com.arm.doc.dui0417d/index.html + * + * we know the registers are mapped to fixed addresses in memory, so we + * can just define a (structured) pointer to each one to support access. + */ + +extern volatile SYSCONF_t* SYSCONF; + +extern volatile uint32_t* SYSCTRL0; +extern volatile uint32_t* SYSCTRL1; + +#endif diff --git a/device/disk.c b/device/disk.c new file mode 100644 index 0000000..f064230 --- /dev/null +++ b/device/disk.c @@ -0,0 +1,114 @@ +#include "disk.h" + +void addr_puth( PL011_t* d, uint32_t x, bool f ) { + PL011_puth( d, ( x >> 0 ) & 0xFF, f ); + PL011_puth( d, ( x >> 8 ) & 0xFF, f ); + PL011_puth( d, ( x >> 16 ) & 0xFF, f ); + PL011_puth( d, ( x >> 24 ) & 0xFF, f ); +} + +void data_puth( PL011_t* d, const uint8_t* x, int n, bool f ) { + for( int i = 0; i < n; i++ ) { + PL011_puth( d, x[ i ], f ); + } +} + +void data_geth( PL011_t* d, uint8_t* x, int n, bool f ) { + for( int i = 0; i < n; i++ ) { + x[ i ] = PL011_geth( d, f ); + } +} + +int disk_get_block_num() { + int n = 2 * sizeof( uint32_t ); uint8_t x[ n ]; + + for( int i = 0; i < DISK_RETRY; i++ ) { + PL011_puth( UART2, 0x00, true ); // write command + PL011_putc( UART2, '\n', true ); // write EOL + + if( PL011_geth( UART2, true ) == 0x00 ) { // read command + PL011_getc( UART2, true ); // read separator + data_geth( UART2, x, n, true ); // read data + PL011_getc( UART2, true ); // read EOL + + return ( ( uint32_t )( x[ 0 ] ) << 0 ) | + ( ( uint32_t )( x[ 1 ] ) << 8 ) | + ( ( uint32_t )( x[ 2 ] ) << 16 ) | + ( ( uint32_t )( x[ 3 ] ) << 24 ) ; + } + else { + PL011_getc( UART2, true ); // read EOL + } + } + + return DISK_FAILURE; +} + +int disk_get_block_len() { + int n = 2 * sizeof( uint32_t ); uint8_t x[ n ]; + + for( int i = 0; i < DISK_RETRY; i++ ) { + PL011_puth( UART2, 0x00, true ); // write command + PL011_putc( UART2, '\n', true ); // write EOL + + if( PL011_geth( UART2, true ) == 0x00 ) { // read command + PL011_getc( UART2, true ); // read separator + data_geth( UART2, x, n, true ); // read data + PL011_getc( UART2, true ); // read EOL + + return ( ( uint32_t )( x[ 4 ] ) << 0 ) | + ( ( uint32_t )( x[ 5 ] ) << 8 ) | + ( ( uint32_t )( x[ 6 ] ) << 16 ) | + ( ( uint32_t )( x[ 7 ] ) << 24 ) ; + } + else { + PL011_getc( UART2, true ); // read EOL + } + } + + return DISK_FAILURE; +} + +int disk_wr( uint32_t a, const uint8_t* x, int n ) { + for( int i = 0; i < DISK_RETRY; i++ ) { + PL011_puth( UART2, 0x01, true ); // write command + PL011_putc( UART2, ' ', true ); // write separator + addr_puth( UART2, a, true ); // write address + PL011_putc( UART2, ' ', true ); // write separator + data_puth( UART2, x, n, true ); // write data + PL011_putc( UART2, '\n', true ); // write EOL + + if( PL011_geth( UART2, true ) == 0x00 ) { // read command + PL011_getc( UART2, true ); // read EOL + + return DISK_SUCCESS; + } + else { + PL011_getc( UART2, true ); // read EOL + } + } + + return DISK_FAILURE; +} + +int disk_rd( uint32_t a, uint8_t* x, int n ) { + for( int i = 0; i < DISK_RETRY; i++ ) { + PL011_puth( UART2, 0x02, true ); // write command + PL011_putc( UART2, ' ', true ); // write separator + addr_puth( UART2, a, true ); // write address + PL011_putc( UART2, '\n', true ); // write EOL + + if( PL011_geth( UART2, true ) == 0x00 ) { // read command + PL011_getc( UART2, true ); // read separator + data_geth( UART2, x, n, true ); // read data + PL011_getc( UART2, true ); // read EOL + + return DISK_SUCCESS; + } + else { + PL011_getc( UART2, true ); // read EOL + } + } + + return DISK_FAILURE; +} diff --git a/device/disk.h b/device/disk.h new file mode 100644 index 0000000..0f0bb46 --- /dev/null +++ b/device/disk.h @@ -0,0 +1,36 @@ +#ifndef __DISK_H +#define __DISK_H + +#include +#include +#include + +#include "PL011.h" + +/* Each of the following functions adopts the same approach to + * reporting success vs. failure, as indicated by the response + * produced by the disk: they return an r st. + * + * r < 0 means failure + * r >= 0 means success + * + * Rather than give up immediately if a given request fails, it + * will (automatically) retry for some fixed number of times. + */ + +#define DISK_RETRY ( 3 ) + +#define DISK_SUCCESS ( 0 ) +#define DISK_FAILURE ( -1 ) + +// query the disk block count +extern int disk_get_block_num(); +// query the disk block length +extern int disk_get_block_len(); + +// write an n-byte block of data x to the disk at block address a +extern int disk_wr( uint32_t a, const uint8_t* x, int n ); +// read an n-byte block of data x from the disk at block address a +extern int disk_rd( uint32_t a, uint8_t* x, int n ); + +#endif diff --git a/device/disk.py b/device/disk.py new file mode 100644 index 0000000..5451a8b --- /dev/null +++ b/device/disk.py @@ -0,0 +1,138 @@ +import argparse, binascii, logging, os, socket, struct, sys + +REQ_CONF = '00' +REQ_WR = '01' +REQ_RD = '02' + +ACK_OKAY = '00' +ACK_FAIL = '01' + +# 00 command means a query operation: we pack the block size +# and count into a single datum, then return it. + +def conf( fd, req ) : + data = struct.pack( '= args.block_num ) : + return [ ACK_FAIL ] + if( len( data ) != args.block_len ) : + return [ ACK_FAIL ] + + os.lseek( fd, address * args.block_len, os.SEEK_SET ) + n = os.write( fd, data ) + + if( len( data ) != n ) : + return [ ACK_FAIL ] + + os.fsync( fd ) + + logging.info( 'wr %d bytes -> address %X_{(16)} = %d_{(10)}' % ( len( data ), address, address ) ) + logging.debug( 'wr data = %s' % ( ''.join( [ '%02X' % ( ord( x ) ) for x in data ] ) ) ) + + return [ ACK_OKAY ] + +# 02 command means a read operation: +# - if the address provided is invalid the request fails, +# - else read the block from the disk, then return the data. + +def rd( fd, req ) : + address = struct.unpack( '= args.block_num ) : + return [ ACK_FAIL ] + + os.lseek( fd, address * args.block_len, os.SEEK_SET ) + data = os.read( fd, args.block_len ) + + if( len( data ) != args.block_len ) : + return [ ACK_FAIL ] + + os.fsync( fd ) + + logging.info( 'rd %d bytes <- address %X_{(16)} = %d_{(10)}' % ( len( data ), address, address ) ) + logging.debug( 'rd data = %s' % ( ''.join( [ '%02X' % ( ord( x ) ) for x in data ] ) ) ) + + return [ ACK_OKAY, data ] + +# The command line interface basically just parses the arguments +# which configure the disk etc. then enters an infinite loop: it +# reads requests and writes acknowledgements one at a time until +# terminated. + +if ( __name__ == '__main__' ) : + # parse command line arguments + + parser = argparse.ArgumentParser() + + parser.add_argument( '--host', type = str, action = 'store' ) + parser.add_argument( '--port', type = int, action = 'store' ) + parser.add_argument( '--file', type = str, action = 'store' ) + + parser.add_argument( '--block-num', type = int, action = 'store' ) + parser.add_argument( '--block-len', type = int, action = 'store' ) + + parser.add_argument( '--debug', action = 'store_true' ) + + args = parser.parse_args() + + if ( args.debug ) : + l = logging.DEBUG + else : + l = logging.INFO + + logging.basicConfig( stream = sys.stdout, level = l, format = '%(filename)s : %(asctime)s : %(message)s', datefmt = '%d/%m/%y @ %H:%M:%S' ) + + # open disk image + + fd = os.open( args.file, os.O_RDWR ) + + # open network connection + + s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) + + s.connect( ( args.host, args.port ) ) ; sd = s.makefile() + + # read request, process it and write acknowledgement + + while ( True ) : + req = sd.readline().strip().split( ' ' ) + + logging.debug( 'req = ' + str( req ) ) + + if ( req[ 0 ] == REQ_CONF ) : + ack = conf( fd, req ) + elif ( req[ 0 ] == REQ_WR ) : + ack = wr( fd, req ) + elif ( req[ 0 ] == REQ_RD ) : + ack = rd( fd, req ) + else : + ack = [ ACK_FAIL ] + + logging.debug( 'ack = ' + str( ack ) ) + + if ( len( ack ) > 1 ) : + ack = ack[ 0 ] + ' ' + ' '.join( [ binascii.hexlify( x ) for x in ack[ 1 : ] ] ) + else : + ack = ack[ 0 ] + + sd.write( ack + '\n' ) ; sd.flush() + + # close network connection + + sd.close() + + # close disk image + + os.close( fd ) diff --git a/image.ld b/image.ld new file mode 100644 index 0000000..081483b --- /dev/null +++ b/image.ld @@ -0,0 +1,18 @@ +SECTIONS { + /* assign load address (per QEMU) */ + . = 0x70010000; + /* place text segment(s) */ + .text : { kernel/lolevel.o(.text) *(.text .rodata) } + /* place data segment(s) */ + .data : { *(.data ) } + /* place bss segment(s) */ + .bss : { *(.bss ) } + /* align address (per AAPCS) */ + . = ALIGN( 8 ); + /* allocate stack for irq mode */ + . = . + 0x00001000; + tos_irq = .; + /* allocate stack for svc mode */ + . = . + 0x00001000; + tos_svc = .; +} diff --git a/kernel/hilevel.c b/kernel/hilevel.c new file mode 100644 index 0000000..224ee21 --- /dev/null +++ b/kernel/hilevel.c @@ -0,0 +1,13 @@ +#include "hilevel.h" + +void hilevel_handler_rst() { + return; +} + +void hilevel_handler_irq() { + return; +} + +void hilevel_handler_svc() { + return; +} diff --git a/kernel/hilevel.h b/kernel/hilevel.h new file mode 100644 index 0000000..7408be9 --- /dev/null +++ b/kernel/hilevel.h @@ -0,0 +1,15 @@ +#ifndef __HILEVEL_H +#define __HILEVEL_H + +// Include functionality relating to newlib (the standard C library). + +#include +#include +#include + +// Include functionality relating to the kernel. + +#include "lolevel.h" +#include "int.h" + +#endif diff --git a/kernel/int.h b/kernel/int.h new file mode 100644 index 0000000..b9a2fa5 --- /dev/null +++ b/kernel/int.h @@ -0,0 +1,20 @@ +#ifndef __INT_H +#define __INT_H + +#include +#include +#include + +// initialise interrupt vector table +extern void int_init(); + +// enable IRQ interrupts +extern void int_enable_irq(); +// disable IRQ interrupts +extern void int_unable_irq(); +// enable FIQ interrupts +extern void int_enable_fiq(); +// disable FIQ interrupts +extern void int_unable_fiq(); + +#endif diff --git a/kernel/int.s b/kernel/int.s new file mode 100644 index 0000000..081c0db --- /dev/null +++ b/kernel/int.s @@ -0,0 +1,69 @@ +/* The following captures the interrupt vector table, plus a function + * to copy it into place (which is called on reset): note that + * + * - for interrupts we don't handle an infinite loop is realised (to + * to approximate halting the processor), and + * - we copy the table itself, *plus* the associated addresses stored + * as static data: this preserves the relative offset between each + * ldr instruction and wherever it loads from. + */ + +int_data: ldr pc, int_addr_rst @ reset vector -> SVC mode + b . @ undefined instruction vector -> UND mode + ldr pc, int_addr_svc @ supervisor call vector -> SVC mode + b . @ pre-fetch abort vector -> ABT mode + b . @ data abort vector -> ABT mode + b . @ reserved + ldr pc, int_addr_irq @ IRQ vector -> IRQ mode + b . @ FIQ vector -> FIQ mode + +int_addr_rst: .word lolevel_handler_rst +int_addr_svc: .word lolevel_handler_svc +int_addr_irq: .word lolevel_handler_irq + +.global int_init + +int_init: mov r0, #0 @ set destination address + ldr r1, =int_data @ set source address = start of data + ldr r2, =int_init @ set source limit = start of function + +l0: ldr r3, [ r1 ], #4 @ load word, inc. source address + str r3, [ r0 ], #4 @ store word, inc. destination address + + cmp r1, r2 + bne l0 @ loop if address != limit + + mov pc, lr @ return + +/* These function enable and disable IRQ and FIQ interrupts, toggling + * either the 6-th or 7-th bit of CPSR to 0 or 1 respectively. + */ + +.global int_enable_irq +.global int_unable_irq +.global int_enable_fiq +.global int_unable_fiq + +int_enable_irq: mrs r0, cpsr @ get USR mode CPSR + bic r0, r0, #0x80 @ enable IRQ interrupts + msr cpsr_c, r0 @ set USR mode CPSR + + mov pc, lr @ return + +int_unable_irq: mrs r0, cpsr @ get USR mode CPSR + orr r0, r0, #0x80 @ disable IRQ interrupts + msr cpsr_c, r0 @ set USR mode CPSR + + mov pc, lr @ return + +int_enable_fiq: mrs r0, cpsr @ get USR mode CPSR + bic r0, r0, #0x40 @ enable FIQ interrupts + msr cpsr_c, r0 @ set USR mode CPSR + + mov pc, lr @ return + +int_unable_fiq: mrs r0, cpsr @ get USR mode CPSR + orr r0, r0, #0x40 @ disable FIQ interrupts + msr cpsr_c, r0 @ set USR mode CPSR + + mov pc, lr @ return diff --git a/kernel/lolevel.h b/kernel/lolevel.h new file mode 100644 index 0000000..ac31e92 --- /dev/null +++ b/kernel/lolevel.h @@ -0,0 +1,4 @@ +#ifndef __LOLEVEL_H +#define __LOLEVEL_H + +#endif diff --git a/kernel/lolevel.s b/kernel/lolevel.s new file mode 100644 index 0000000..51beda3 --- /dev/null +++ b/kernel/lolevel.s @@ -0,0 +1,34 @@ +/* Each of the following is a low-level interrupt handler: each one is + * tasked with handling a different interrupt type, and acts as a sort + * of wrapper around a high-level, C-based handler. + */ + +.global lolevel_handler_rst +.global lolevel_handler_irq +.global lolevel_handler_svc + +lolevel_handler_rst: bl int_init @ initialise interrupt vector table + + msr cpsr, #0xD2 @ enter IRQ mode with IRQ and FIQ interrupts disabled + ldr sp, =tos_irq @ initialise IRQ mode stack + msr cpsr, #0xD3 @ enter SVC mode with IRQ and FIQ interrupts disabled + ldr sp, =tos_svc @ initialise SVC mode stack + + bl hilevel_handler_rst @ invoke high-level C function + b . @ halt + +lolevel_handler_irq: sub lr, lr, #4 @ correct return address + stmfd sp!, { r0-r3, ip, lr } @ save caller-save registers + + bl hilevel_handler_irq @ invoke high-level C function + + ldmfd sp!, { r0-r3, ip, lr } @ restore caller-save registers + movs pc, lr @ return from interrupt + +lolevel_handler_svc: sub lr, lr, #0 @ correct return address + stmfd sp!, { r0-r3, ip, lr } @ save caller-save registers + + bl hilevel_handler_svc @ invoke high-level C function + + ldmfd sp!, { r0-r3, ip, lr } @ restore caller-save registers + movs pc, lr @ return from interrupt diff --git a/question.pdf b/question.pdf new file mode 100644 index 0000000000000000000000000000000000000000..46b14ea33c7876be7fe1ef05f4e33066f3947f6f GIT binary patch literal 140249 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 literal 0 HcmV?d00001 diff --git a/user/P3.c b/user/P3.c new file mode 100644 index 0000000..3c29c79 --- /dev/null +++ b/user/P3.c @@ -0,0 +1,30 @@ +#include "P3.h" + +int is_prime( uint32_t x ) { + if ( !( x & 1 ) || ( x < 2 ) ) { + return ( x == 2 ); + } + + for( uint32_t d = 3; ( d * d ) <= x ; d += 2 ) { + if( !( x % d ) ) { + return 0; + } + } + + return 1; +} + +void main_P3() { + for( int i = 0; i < 50; i++ ) { + write( STDOUT_FILENO, "P3", 2 ); + + uint32_t lo = 1 << 8; + uint32_t hi = 1 << 16; + + for( uint32_t x = lo; x < hi; x++ ) { + int r = is_prime( x ); + } + } + + exit( EXIT_SUCCESS ); +} diff --git a/user/P3.h b/user/P3.h new file mode 100644 index 0000000..966dec4 --- /dev/null +++ b/user/P3.h @@ -0,0 +1,10 @@ +#ifndef __P3_H +#define __P3_H + +#include +#include +#include + +#include "libc.h" + +#endif diff --git a/user/P4.c b/user/P4.c new file mode 100644 index 0000000..312e558 --- /dev/null +++ b/user/P4.c @@ -0,0 +1,30 @@ +#include "P4.h" + +uint32_t gcd( uint32_t x, uint32_t y ) { + if ( x == y ) { + return x; + } + else if( x > y ) { + return gcd( x - y, y ); + } + else if( x < y ) { + return gcd( x, y - x ); + } +} + +void main_P4() { + while( 1 ) { + write( STDOUT_FILENO, "P4", 2 ); + + uint32_t lo = 1 << 4; + uint32_t hi = 1 << 8; + + for( uint32_t x = lo; x < hi; x++ ) { + for( uint32_t y = lo; y < hi; y++ ) { + uint32_t r = gcd( x, y ); + } + } + } + + exit( EXIT_SUCCESS ); +} diff --git a/user/P4.h b/user/P4.h new file mode 100644 index 0000000..8ec205b --- /dev/null +++ b/user/P4.h @@ -0,0 +1,10 @@ +#ifndef __P4_H +#define __P4_H + +#include +#include +#include + +#include "libc.h" + +#endif diff --git a/user/P5.c b/user/P5.c new file mode 100644 index 0000000..53523c5 --- /dev/null +++ b/user/P5.c @@ -0,0 +1,26 @@ +#include "P5.h" + +uint32_t weight( uint32_t x ) { + x = ( x & 0x55555555 ) + ( ( x >> 1 ) & 0x55555555 ); + x = ( x & 0x33333333 ) + ( ( x >> 2 ) & 0x33333333 ); + x = ( x & 0x0F0F0F0F ) + ( ( x >> 4 ) & 0x0F0F0F0F ); + x = ( x & 0x00FF00FF ) + ( ( x >> 8 ) & 0x00FF00FF ); + x = ( x & 0x0000FFFF ) + ( ( x >> 16 ) & 0x0000FFFF ); + + return x; +} + +void main_P5() { + while( 1 ) { + write( STDOUT_FILENO, "P5", 2 ); + + uint32_t lo = 1 << 8; + uint32_t hi = 1 << 24; + + for( uint32_t x = lo; x < hi; x++ ) { + uint32_t r = weight( x ); + } + } + + exit( EXIT_SUCCESS ); +} diff --git a/user/P5.h b/user/P5.h new file mode 100644 index 0000000..e6f31c2 --- /dev/null +++ b/user/P5.h @@ -0,0 +1,10 @@ +#ifndef __P5_H +#define __P5_H + +#include +#include +#include + +#include "libc.h" + +#endif diff --git a/user/console.c b/user/console.c new file mode 100644 index 0000000..a59ebb4 --- /dev/null +++ b/user/console.c @@ -0,0 +1,83 @@ +#include "console.h" + +/* The following functions are special-case versions of a) writing, + * and b) reading a string from the UART (the latter case returning + * once a carriage return character has been read, or an overall + * limit reached). + */ + +void puts( char* x, int n ) { + for( int i = 0; i < n; i++ ) { + PL011_putc( UART1, x[ i ], true ); + } +} + +void gets( char* x, int n ) { + for( int i = 0; i < n; i++ ) { + x[ i ] = PL011_getc( UART1, true ); + + if( x[ i ] == '\x0A' ) { + x[ i ] = '\x00'; break; + } + } +} + +/* Since we lack a *real* loader (as a result of lacking a storage + * medium to store program images), the following approximates one: + * given a program name, from the set of programs statically linked + * into the kernel image, it returns a pointer to the entry point. + */ + +extern void main_P3(); +extern void main_P4(); +extern void main_P5(); + +void* load( char* x ) { + if ( 0 == strcmp( x, "P3" ) ) { + return &main_P3; + } + else if( 0 == strcmp( x, "P4" ) ) { + return &main_P4; + } + else if( 0 == strcmp( x, "P5" ) ) { + return &main_P5; + } + + return NULL; +} + +/* The behaviour of the console process can be summarised as an + * (infinite) loop over three main steps, namely + * + * 1. write a command prompt then read a command, + * 2. split the command into space-separated tokens using strtok, + * 3. execute whatever steps the command dictates. + */ + +void main_console() { + char* p, x[ 1024 ]; + + while( 1 ) { + puts( "shell$ ", 7 ); gets( x, 1024 ); p = strtok( x, " " ); + + if ( 0 == strcmp( p, "fork" ) ) { + pid_t pid = fork(); + + if( 0 == pid ) { + void* addr = load( strtok( NULL, " " ) ); + exec( addr ); + } + } + else if( 0 == strcmp( p, "kill" ) ) { + pid_t pid = atoi( strtok( NULL, " " ) ); + int s = atoi( strtok( NULL, " " ) ); + + kill( pid, s ); + } + else { + puts( "unknown command\n", 16 ); + } + } + + exit( EXIT_SUCCESS ); +} diff --git a/user/console.h b/user/console.h new file mode 100644 index 0000000..39867fd --- /dev/null +++ b/user/console.h @@ -0,0 +1,14 @@ +#ifndef __CONSOLE_H +#define __CONSOLE_H + +#include +#include +#include + +#include + +#include "PL011.h" + +#include "libc.h" + +#endif diff --git a/user/libc.c b/user/libc.c new file mode 100644 index 0000000..f376f15 --- /dev/null +++ b/user/libc.c @@ -0,0 +1,131 @@ +#include "libc.h" + +int atoi( char* x ) { + char* p = x; bool s = false; int r = 0; + + if ( *p == '-' ) { + s = true; p++; + } + else if( *p == '+' ) { + s = false; p++; + } + + for( int i = 0; *p != '\x00'; i++, p++ ) { + r = s ? ( r * 10 ) - ( *p - '0' ) : + ( r * 10 ) + ( *p - '0' ) ; + } + + return r; +} + +void itoa( char* r, int x ) { + char* p = r; int t, n; + + if( x < 0 ) { + p++; t = -x; n = 1; + } + else { + t = +x; n = 1; + } + + while( t >= n ) { + p++; n *= 10; + } + + *p-- = '\x00'; + + do { + *p-- = '0' + ( t % 10 ); t /= 10; + } while( t ); + + if( x < 0 ) { + *p-- = '-'; + } + + return; +} + +void yield() { + asm volatile( "svc %0 \n" // make system call SYS_YIELD + : + : "I" (SYS_YIELD) + : ); + + return; +} + +int write( int fd, const void* x, size_t n ) { + int r; + + asm volatile( "mov r0, %2 \n" // assign r0 = fd + "mov r1, %3 \n" // assign r1 = x + "mov r2, %4 \n" // assign r2 = n + "svc %1 \n" // make system call SYS_WRITE + "mov %0, r0 \n" // assign r = r0 + : "=r" (r) + : "I" (SYS_WRITE), "r" (fd), "r" (x), "r" (n) + : "r0", "r1", "r2" ); + + return r; +} + +int read( int fd, void* x, size_t n ) { + int r; + + asm volatile( "mov r0, %2 \n" // assign r0 = fd + "mov r1, %3 \n" // assign r1 = x + "mov r2, %4 \n" // assign r2 = n + "svc %1 \n" // make system call SYS_READ + "mov %0, r0 \n" // assign r = r0 + : "=r" (r) + : "I" (SYS_READ), "r" (fd), "r" (x), "r" (n) + : "r0", "r1", "r2" ); + + return r; +} + +int fork() { + int r; + + asm volatile( "svc %1 \n" // make system call SYS_FORK + "mov %0, r0 \n" // assign r = r0 + : "=r" (r) + : "I" (SYS_FORK) + : "r0" ); + + return r; +} + +void exit( int x ) { + asm volatile( "mov r0, %1 \n" // assign r0 = x + "svc %0 \n" // make system call SYS_EXIT + : + : "I" (SYS_EXIT), "r" (x) + : "r0" ); + + return; +} + +void exec( const void* x ) { + asm volatile( "mov r0, %1 \n" // assign r0 = x + "svc %0 \n" // make system call SYS_EXEC + : + : "I" (SYS_EXEC), "r" (x) + : "r0" ); + + return; +} + +int kill( int pid, int x ) { + int r; + + asm volatile( "mov r0, %2 \n" // assign r0 = pid + "mov r1, %3 \n" // assign r1 = x + "svc %1 \n" // make system call SYS_KILL + "mov %0, r0 \n" // assign r0 = r + : "=r" (r) + : "I" (SYS_KILL), "r" (pid), "r" (x) + : "r0", "r1" ); + + return r; +} diff --git a/user/libc.h b/user/libc.h new file mode 100644 index 0000000..02af5dc --- /dev/null +++ b/user/libc.h @@ -0,0 +1,67 @@ +#ifndef __LIBC_H +#define __LIBC_H + +#include +#include +#include + +// Define a type that that captures a Process IDentifier (PID). + +typedef int pid_t; + +/* The definitions below capture symbolic constants within these classes: + * + * 1. system call identifiers (i.e., the constant used by a system call + * to specify which action the kernel should take), + * 2. signal identifiers (as used by the kill system call), + * 3. status codes for exit, + * 4. standard file descriptors (e.g., for read and write system calls), + * 5. platform-specific constants, which may need calibration (wrt. the + * underlying hardware QEMU is executed on). + * + * They don't *precisely* match the standard C library, but are intended + * to act as a limited model of similar concepts. + */ + +#define SYS_YIELD ( 0x00 ) +#define SYS_WRITE ( 0x01 ) +#define SYS_READ ( 0x02 ) +#define SYS_FORK ( 0x03 ) +#define SYS_EXIT ( 0x04 ) +#define SYS_EXEC ( 0x05 ) +#define SYS_KILL ( 0x06 ) + +#define SIG_TERM ( 0x00 ) +#define SIG_QUIT ( 0x01 ) + +#define EXIT_SUCCESS ( 0 ) +#define EXIT_FAILURE ( 1 ) + +#define STDIN_FILENO ( 0 ) +#define STDOUT_FILENO ( 1 ) +#define STDERR_FILENO ( 2 ) + +// convert ASCII string x into integer r +extern int atoi( char* x ); +// convert integer x into ASCII string r +extern void itoa( char* r, int x ); + +// cooperatively yield control of processor, i.e., invoke the scheduler +extern void yield(); + +// write n bytes from x to the file descriptor fd; return bytes written +extern int write( int fd, const void* x, size_t n ); +// read n bytes into x from the file descriptor fd; return bytes read +extern int read( int fd, void* x, size_t n ); + +// perform fork, returning 0 iff. child or > 0 iff. parent process +extern int fork(); +// perform exit, i.e., terminate process with status x +extern void exit( int x ); +// perform exec, i.e., start executing program at address x +extern void exec( const void* x ); + +// signal process identified by pid with signal x +extern int kill( pid_t pid, int x ); + +#endif