Browse Source

Compila y llego a nulluser

pull/1/head
Rafael Zurita 6 years ago
commit
6f0cd91423
  1. 20
      LICENSE
  2. 34
      README.md
  3. 318
      compile/.defs
  4. 2683
      compile/.deps
  5. 1
      compile/.vers_num
  6. 1
      compile/DAC_OUT_PUT1.txt
  7. 1
      compile/DAC_OUT_PUT2.txt
  8. 199
      compile/Makefile
  9. 710
      compile/bin/build-make
  10. 27
      compile/bin/mkvers
  11. BIN
      compile/binaries/getchar.o
  12. BIN
      compile/binaries/putchar.o
  13. BIN
      compile/binaries/qsort.o
  14. 189
      compile/original/Makefile.orig
  15. 1
      compile/original/flash.sh
  16. 135
      compile/original/ld.script
  17. 135
      compile/original/ld.script.avr
  18. 105
      compile/original/ld.script.avr.baremetal
  19. 149
      compile/original/ld.script.avr2
  20. 55
      compile/original/ld.script.stm32
  21. 1
      compile/version
  22. 1108
      compile/xinu.hex
  23. 1332
      compile/xinu.map
  24. 119
      config/Configuration
  25. 106
      config/Configuration.orig
  26. 111
      config/DESCRIPTION
  27. 41
      config/Makefile
  28. 44
      config/conf.c
  29. 50
      config/conf.h
  30. 40
      config/config.l
  31. 754
      config/config.y
  32. 35
      device/eth/ethcontrol.c
  33. 123
      device/eth/ethhandler.c
  34. 403
      device/eth/ethinit.c
  35. 69
      device/eth/ethread.c
  36. 84
      device/eth/ethwrite.c
  37. 40
      device/lfs/lfdballoc.c
  38. 25
      device/lfs/lfdbfree.c
  39. 42
      device/lfs/lfflush.c
  40. 61
      device/lfs/lfgetmode.c
  41. 33
      device/lfs/lfiballoc.c
  42. 22
      device/lfs/lfibclear.c
  43. 31
      device/lfs/lfibget.c
  44. 43
      device/lfs/lfibput.c
  45. 38
      device/lfs/lflclose.c
  46. 47
      device/lfs/lflcontrol.c
  47. 52
      device/lfs/lflgetc.c
  48. 46
      device/lfs/lflinit.c
  49. 64
      device/lfs/lflputc.c
  50. 39
      device/lfs/lflread.c
  51. 41
      device/lfs/lflseek.c
  52. 29
      device/lfs/lflwrite.c
  53. 40
      device/lfs/lfscheck.c
  54. 65
      device/lfs/lfsckfmt.c
  55. 74
      device/lfs/lfscreate.c
  56. 122
      device/lfs/lfsetup.c
  57. 32
      device/lfs/lfsinit.c
  58. 185
      device/lfs/lfsopen.c
  59. 104
      device/lfs/lftruncate.c
  60. 64
      device/movidos/gpio/gpiocontrol.c
  61. 85
      device/movidos/gpio/gpiohandler.c
  62. 42
      device/movidos/gpio/gpioinit.c
  63. 27
      device/movidos/gpio/gpioread.c
  64. 25
      device/movidos/gpio/gpioselect.c
  65. 31
      device/movidos/gpio/gpiowrite.c
  66. 14
      device/movidos/ram/ramclose.c
  67. 19
      device/movidos/ram/raminit.c
  68. 19
      device/movidos/ram/ramopen.c
  69. 21
      device/movidos/ram/ramread.c
  70. 21
      device/movidos/ram/ramwrite.c
  71. 58
      device/movidos/tty/ttycontrol.c
  72. 41
      device/movidos/tty/ttygetc.c
  73. 267
      device/movidos/tty/ttyhandle_in.c
  74. 83
      device/movidos/tty/ttyhandle_out.c
  75. 114
      device/movidos/tty/ttyhandler.c
  76. 83
      device/movidos/tty/ttyinit.c
  77. 19
      device/movidos/tty/ttykickout.c
  78. 44
      device/movidos/tty/ttyputc.c
  79. 68
      device/movidos/tty/ttyread.c
  80. 29
      device/movidos/tty/ttywrite.c
  81. 76
      device/nam/mount.c
  82. 93
      device/nam/naminit.c
  83. 135
      device/nam/nammap.c
  84. 29
      device/nam/namopen.c
  85. 50
      device/rds/rdsbufalloc.c
  86. 60
      device/rds/rdsclose.c
  87. 124
      device/rds/rdscomm.c
  88. 131
      device/rds/rdscontrol.c
  89. 108
      device/rds/rdsinit.c
  90. 93
      device/rds/rdsopen.c
  91. 212
      device/rds/rdsprocess.c
  92. 130
      device/rds/rdsread.c
  93. 97
      device/rds/rdswrite.c
  94. 32
      device/rfs/rflclose.c
  95. 23
      device/rfs/rflgetc.c
  96. 29
      device/rfs/rflinit.c
  97. 19
      device/rfs/rflputc.c
  98. 100
      device/rfs/rflread.c
  99. 33
      device/rfs/rflseek.c
  100. 97
      device/rfs/rflwrite.c
  101. Some files were not shown because too many files have changed in this diff Show More

20
LICENSE

@ -0,0 +1,20 @@
Portions of this software are covered by the following copyright:
Copyright (c) 2012, 2015 Douglas E. Comer and CRC Press, Inc.
All rights reserved.
Redistribution and use in source and binary forms are permitted
provided that this notice is preserved and that due credit is given
to the copyright holders. The names of the copyright holders
may not be used to endorse or promote products derived from this
software without specific prior written permission. This software
is provided `as is'' without express or implied warranty. The author
assumes no liability for damages incidental or consequential, nor is the
software warranted for correctness or suitability for any purpose.
Portions of this software are documented in the book:
Operating System Design -- The Xinu Approach, CRC Press,
Boca Raton, FL, Linksys version 2012, Second Edition 2015.
This software may not be sold or published in printed form without written
permission from the copyright holders.

34
README.md

@ -0,0 +1,34 @@
## What is Xinu?
Xinu stands for Xinu Is Not Unix -- although it shares concepts and even names with Unix, the internal design differs completely. Xinu is a small, elegant operating system that supports dynamic process creation, dynamic memory allocation, network communication, local and remote file systems, a shell, and device-independent I/O functions. The small size makes Xinu suitable for embedded environments.
## What is Xinu for STM32
Xinu for STM32 is a port of the ARM version of Xinu. The STM32 family of 32-bit microcontrollers is a popular SoC based on the Arm Cortex-M processor.
Besides porting the original version, Xinu for STM32 is extended with the following specific Cortex-M* features:
* Shadowed Stack Pointer: Two stack pointers are available. The MSP is used
for the OS Kernel and interrupt handlers. The PSP is used by application
tasks.
* PendSV exception for scheduling: If Xinu decides that context switching is needed,
it sets the pending status of the PendSV, and delays the context-switching
request until all other IRQ handlers have completed their processing before
carrying out the PendSV exception
## Supported Peripherals (currently)
* UART (Serial)
* GPIO
* SPI
## Tested boards
1. STM32F103* - https://stm32-base.org/boards/STM32F103RCT6-STM32-Mini-V2.0
2. Qemu for STM32 - https://github.com/beckus/qemu_stm32
## How to build and run
Xinu for STM32 uses simple Makefiles. The source code should be compiled with a cross compiler (i.e. Ubuntu's standard package: GCC cross compiler for ARM Cortex-A/R/M processors)
STM32Flash (https://sourceforge.net/projects/stm32flash) can be used for flashing the compiled code to the device's flash ROM. Use `qemu make` to run Xinu for STM32 in Qemu. Please note that this version of qemu should be manually build (see https://github.com/beckus/qemu_stm32)
## Screenshots
![Screenshot](https://github.com/robinkrens/xinu-for-stm32/raw/master/screenshot.png "bootscreen")
More general information about Xinu can be found at https://xinu.cs.purdue.edu/

318
compile/.defs

@ -0,0 +1,318 @@
#-------------------------------------------------------------------------------#
# #
# Definitions generated by build-make on dom may 17 23:40:51 -03 2020 #
# #
#-------------------------------------------------------------------------------#
SRC_CFILES =
SRC_SFILES =
#------------------------------------------------------------------
#
# Directory ../system
#
#------------------------------------------------------------------
SYSTEM_SFILES = \
intr.S start.S
SYSTEM_CFILES = \
ascdate.c blink_avr.c bufinit.c chprio.c clkhandler.c \
clkinit.c close.c conf.c control.c create.c \
debug.c evec.c exit.c freebuf.c freemem.c \
getbuf.c getc.c getdev.c getitem.c getmem.c \
getpid.c getprio.c getstk.c getticks.c gettime.c \
init.c initialize.c insert.c insertd.c ioerr.c \
ionull.c kill.c kprintf.c main.c mark.c \
meminit.c mkbufpool.c newqueue.c open.c panic.c \
platinit.c ptclear.c ptcount.c ptcreate.c ptdelete.c \
ptinit.c ptrecv.c ptreset.c ptsend.c putc.c \
queue.c read.c ready.c receive.c recvclr.c \
recvtime.c resched.c resume.c seek.c semcount.c \
semcreate.c semdelete.c semreset.c send.c serial_avr.c \
signal.c signaln.c sleep.c suspend.c syscall.c \
unsleep.c userret.c wait.c wakeup.c write.c \
xdone.c yield.c
SRC_CFILES += ${SYSTEM_CFILES}
SRC_SFILES += ${SYSTEM_SFILES}
SYSTEM_CFULL += ${SYSTEM_CFILES:%=../system/%}
SYSTEM_SFULL += ${SYSTEM_SFILES:%=../system/%}
SRC_CFULL += ${SYSTEM_CFULL}
SRC_SFULL += ${SYSTEM_SFULL}
#------------------------------------------------------------------
#
# Directory ../lib
#
#------------------------------------------------------------------
LIB_CFILES = \
ctype_.c doprnt.c doscan.c messages.c userland.c
SRC_CFILES += ${LIB_CFILES}
LIB_CFULL += ${LIB_CFILES:%=../lib/%}
SRC_CFULL += ${LIB_CFULL}
#------------------------------------------------------------------
#
# Directory ../device/nam
#
#------------------------------------------------------------------
DEVICE_NAM_CFILES = \
mount.c naminit.c nammap.c namopen.c
SRC_CFILES += ${DEVICE_NAM_CFILES}
DEVICE_NAM_CFULL += ${DEVICE_NAM_CFILES:%=../device/nam/%}
SRC_CFULL += ${DEVICE_NAM_CFULL}
#------------------------------------------------------------------
#
# Directory ../shell
#
#------------------------------------------------------------------
SHELL_CFILES = \
addargs.c lexan.c shell.c
SRC_CFILES += ${SHELL_CFILES}
SHELL_CFULL += ${SHELL_CFILES:%=../shell/%}
SRC_CFULL += ${SHELL_CFULL}
#-------------------------------------------------------------------------------#
# #
# Rules For Generating Object Files #
# #
#-------------------------------------------------------------------------------#
OBJ_TMP = ${patsubst %.s,%.o,$(SRC_SFILES)} # substitute .s => .o
OBJ_SFILES = ${patsubst %.S,%.o,$(OBJ_TMP)} # substitute .S => .o
OBJ_CFILES = ${patsubst %.c,%.o,$(SRC_CFILES)} # substitute .c => .o
OBJ_LIST = ${OBJ_CFILES} ${OBJ_SFILES}
OBJ_FILES = ${OBJ_LIST:%=binaries/%}
SRC_FULL = ${SRC_CFULL} ${SRC_SFULL}
#------------------------------------------------------------------
# Rules for files in directory ../system
#------------------------------------------------------------------
binaries/intr.o: ../system/intr.S
${CC} ${CFLAGS} -o binaries/intr.o ../system/intr.S
binaries/start.o: ../system/start.S
${CC} ${CFLAGS} -o binaries/start.o ../system/start.S
binaries/ascdate.o: ../system/ascdate.c
${CC} ${CFLAGS} -o binaries/ascdate.o ../system/ascdate.c
binaries/blink_avr.o: ../system/blink_avr.c
${CC} ${CFLAGS} -o binaries/blink_avr.o ../system/blink_avr.c
binaries/bufinit.o: ../system/bufinit.c
${CC} ${CFLAGS} -o binaries/bufinit.o ../system/bufinit.c
binaries/chprio.o: ../system/chprio.c
${CC} ${CFLAGS} -o binaries/chprio.o ../system/chprio.c
binaries/clkhandler.o: ../system/clkhandler.c
${CC} ${CFLAGS} -o binaries/clkhandler.o ../system/clkhandler.c
binaries/clkinit.o: ../system/clkinit.c
${CC} ${CFLAGS} -o binaries/clkinit.o ../system/clkinit.c
binaries/close.o: ../system/close.c
${CC} ${CFLAGS} -o binaries/close.o ../system/close.c
binaries/conf.o: ../system/conf.c
${CC} ${CFLAGS} -o binaries/conf.o ../system/conf.c
binaries/control.o: ../system/control.c
${CC} ${CFLAGS} -o binaries/control.o ../system/control.c
binaries/create.o: ../system/create.c
${CC} ${CFLAGS} -o binaries/create.o ../system/create.c
binaries/debug.o: ../system/debug.c
${CC} ${CFLAGS} -o binaries/debug.o ../system/debug.c
binaries/evec.o: ../system/evec.c
${CC} ${CFLAGS} -o binaries/evec.o ../system/evec.c
binaries/exit.o: ../system/exit.c
${CC} ${CFLAGS} -o binaries/exit.o ../system/exit.c
binaries/freebuf.o: ../system/freebuf.c
${CC} ${CFLAGS} -o binaries/freebuf.o ../system/freebuf.c
binaries/freemem.o: ../system/freemem.c
${CC} ${CFLAGS} -o binaries/freemem.o ../system/freemem.c
binaries/getbuf.o: ../system/getbuf.c
${CC} ${CFLAGS} -o binaries/getbuf.o ../system/getbuf.c
binaries/getc.o: ../system/getc.c
${CC} ${CFLAGS} -o binaries/getc.o ../system/getc.c
binaries/getdev.o: ../system/getdev.c
${CC} ${CFLAGS} -o binaries/getdev.o ../system/getdev.c
binaries/getitem.o: ../system/getitem.c
${CC} ${CFLAGS} -o binaries/getitem.o ../system/getitem.c
binaries/getmem.o: ../system/getmem.c
${CC} ${CFLAGS} -o binaries/getmem.o ../system/getmem.c
binaries/getpid.o: ../system/getpid.c
${CC} ${CFLAGS} -o binaries/getpid.o ../system/getpid.c
binaries/getprio.o: ../system/getprio.c
${CC} ${CFLAGS} -o binaries/getprio.o ../system/getprio.c
binaries/getstk.o: ../system/getstk.c
${CC} ${CFLAGS} -o binaries/getstk.o ../system/getstk.c
binaries/getticks.o: ../system/getticks.c
${CC} ${CFLAGS} -o binaries/getticks.o ../system/getticks.c
binaries/gettime.o: ../system/gettime.c
${CC} ${CFLAGS} -o binaries/gettime.o ../system/gettime.c
binaries/init.o: ../system/init.c
${CC} ${CFLAGS} -o binaries/init.o ../system/init.c
binaries/initialize.o: ../system/initialize.c
${CC} ${CFLAGS} -o binaries/initialize.o ../system/initialize.c
binaries/insert.o: ../system/insert.c
${CC} ${CFLAGS} -o binaries/insert.o ../system/insert.c
binaries/insertd.o: ../system/insertd.c
${CC} ${CFLAGS} -o binaries/insertd.o ../system/insertd.c
binaries/ioerr.o: ../system/ioerr.c
${CC} ${CFLAGS} -o binaries/ioerr.o ../system/ioerr.c
binaries/ionull.o: ../system/ionull.c
${CC} ${CFLAGS} -o binaries/ionull.o ../system/ionull.c
binaries/kill.o: ../system/kill.c
${CC} ${CFLAGS} -o binaries/kill.o ../system/kill.c
binaries/kprintf.o: ../system/kprintf.c
${CC} ${CFLAGS} -o binaries/kprintf.o ../system/kprintf.c
binaries/main.o: ../system/main.c
${CC} ${CFLAGS} -o binaries/main.o ../system/main.c
binaries/mark.o: ../system/mark.c
${CC} ${CFLAGS} -o binaries/mark.o ../system/mark.c
binaries/meminit.o: ../system/meminit.c
${CC} ${CFLAGS} -o binaries/meminit.o ../system/meminit.c
binaries/mkbufpool.o: ../system/mkbufpool.c
${CC} ${CFLAGS} -o binaries/mkbufpool.o ../system/mkbufpool.c
binaries/newqueue.o: ../system/newqueue.c
${CC} ${CFLAGS} -o binaries/newqueue.o ../system/newqueue.c
binaries/open.o: ../system/open.c
${CC} ${CFLAGS} -o binaries/open.o ../system/open.c
binaries/panic.o: ../system/panic.c
${CC} ${CFLAGS} -o binaries/panic.o ../system/panic.c
binaries/platinit.o: ../system/platinit.c
${CC} ${CFLAGS} -o binaries/platinit.o ../system/platinit.c
binaries/ptclear.o: ../system/ptclear.c
${CC} ${CFLAGS} -o binaries/ptclear.o ../system/ptclear.c
binaries/ptcount.o: ../system/ptcount.c
${CC} ${CFLAGS} -o binaries/ptcount.o ../system/ptcount.c
binaries/ptcreate.o: ../system/ptcreate.c
${CC} ${CFLAGS} -o binaries/ptcreate.o ../system/ptcreate.c
binaries/ptdelete.o: ../system/ptdelete.c
${CC} ${CFLAGS} -o binaries/ptdelete.o ../system/ptdelete.c
binaries/ptinit.o: ../system/ptinit.c
${CC} ${CFLAGS} -o binaries/ptinit.o ../system/ptinit.c
binaries/ptrecv.o: ../system/ptrecv.c
${CC} ${CFLAGS} -o binaries/ptrecv.o ../system/ptrecv.c
binaries/ptreset.o: ../system/ptreset.c
${CC} ${CFLAGS} -o binaries/ptreset.o ../system/ptreset.c
binaries/ptsend.o: ../system/ptsend.c
${CC} ${CFLAGS} -o binaries/ptsend.o ../system/ptsend.c
binaries/putc.o: ../system/putc.c
${CC} ${CFLAGS} -o binaries/putc.o ../system/putc.c
binaries/queue.o: ../system/queue.c
${CC} ${CFLAGS} -o binaries/queue.o ../system/queue.c
binaries/read.o: ../system/read.c
${CC} ${CFLAGS} -o binaries/read.o ../system/read.c
binaries/ready.o: ../system/ready.c
${CC} ${CFLAGS} -o binaries/ready.o ../system/ready.c
binaries/receive.o: ../system/receive.c
${CC} ${CFLAGS} -o binaries/receive.o ../system/receive.c
binaries/recvclr.o: ../system/recvclr.c
${CC} ${CFLAGS} -o binaries/recvclr.o ../system/recvclr.c
binaries/recvtime.o: ../system/recvtime.c
${CC} ${CFLAGS} -o binaries/recvtime.o ../system/recvtime.c
binaries/resched.o: ../system/resched.c
${CC} ${CFLAGS} -o binaries/resched.o ../system/resched.c
binaries/resume.o: ../system/resume.c
${CC} ${CFLAGS} -o binaries/resume.o ../system/resume.c
binaries/seek.o: ../system/seek.c
${CC} ${CFLAGS} -o binaries/seek.o ../system/seek.c
binaries/semcount.o: ../system/semcount.c
${CC} ${CFLAGS} -o binaries/semcount.o ../system/semcount.c
binaries/semcreate.o: ../system/semcreate.c
${CC} ${CFLAGS} -o binaries/semcreate.o ../system/semcreate.c
binaries/semdelete.o: ../system/semdelete.c
${CC} ${CFLAGS} -o binaries/semdelete.o ../system/semdelete.c
binaries/semreset.o: ../system/semreset.c
${CC} ${CFLAGS} -o binaries/semreset.o ../system/semreset.c
binaries/send.o: ../system/send.c
${CC} ${CFLAGS} -o binaries/send.o ../system/send.c
binaries/serial_avr.o: ../system/serial_avr.c
${CC} ${CFLAGS} -o binaries/serial_avr.o ../system/serial_avr.c
binaries/signal.o: ../system/signal.c
${CC} ${CFLAGS} -o binaries/signal.o ../system/signal.c
binaries/signaln.o: ../system/signaln.c
${CC} ${CFLAGS} -o binaries/signaln.o ../system/signaln.c
binaries/sleep.o: ../system/sleep.c
${CC} ${CFLAGS} -o binaries/sleep.o ../system/sleep.c
binaries/suspend.o: ../system/suspend.c
${CC} ${CFLAGS} -o binaries/suspend.o ../system/suspend.c
binaries/syscall.o: ../system/syscall.c
${CC} ${CFLAGS} -o binaries/syscall.o ../system/syscall.c
binaries/unsleep.o: ../system/unsleep.c
${CC} ${CFLAGS} -o binaries/unsleep.o ../system/unsleep.c
binaries/userret.o: ../system/userret.c
${CC} ${CFLAGS} -o binaries/userret.o ../system/userret.c
binaries/wait.o: ../system/wait.c
${CC} ${CFLAGS} -o binaries/wait.o ../system/wait.c
binaries/wakeup.o: ../system/wakeup.c
${CC} ${CFLAGS} -o binaries/wakeup.o ../system/wakeup.c
binaries/write.o: ../system/write.c
${CC} ${CFLAGS} -o binaries/write.o ../system/write.c
binaries/xdone.o: ../system/xdone.c
${CC} ${CFLAGS} -o binaries/xdone.o ../system/xdone.c
binaries/yield.o: ../system/yield.c
${CC} ${CFLAGS} -o binaries/yield.o ../system/yield.c
#------------------------------------------------------------------
# Rules for files in directory ../lib
#------------------------------------------------------------------
binaries/ctype_.o: ../lib/ctype_.c
${CC} ${CFLAGS} -o binaries/ctype_.o ../lib/ctype_.c
binaries/doprnt.o: ../lib/doprnt.c
${CC} ${CFLAGS} -o binaries/doprnt.o ../lib/doprnt.c
binaries/doscan.o: ../lib/doscan.c
${CC} ${CFLAGS} -o binaries/doscan.o ../lib/doscan.c
binaries/messages.o: ../lib/messages.c
${CC} ${CFLAGS} -o binaries/messages.o ../lib/messages.c
binaries/userland.o: ../lib/userland.c
${CC} ${CFLAGS} -o binaries/userland.o ../lib/userland.c
#------------------------------------------------------------------
# Rules for files in directory ../device/nam
#------------------------------------------------------------------
binaries/mount.o: ../device/nam/mount.c
${CC} ${CFLAGS} -o binaries/mount.o ../device/nam/mount.c
binaries/naminit.o: ../device/nam/naminit.c
${CC} ${CFLAGS} -o binaries/naminit.o ../device/nam/naminit.c
binaries/nammap.o: ../device/nam/nammap.c
${CC} ${CFLAGS} -o binaries/nammap.o ../device/nam/nammap.c
binaries/namopen.o: ../device/nam/namopen.c
${CC} ${CFLAGS} -o binaries/namopen.o ../device/nam/namopen.c
#------------------------------------------------------------------
# Rules for files in directory ../shell
#------------------------------------------------------------------
binaries/addargs.o: ../shell/addargs.c
${CC} ${CFLAGS} -o binaries/addargs.o ../shell/addargs.c
binaries/lexan.o: ../shell/lexan.c
${CC} ${CFLAGS} -o binaries/lexan.o ../shell/lexan.c
binaries/shell.o: ../shell/shell.c
${CC} ${CFLAGS} -o binaries/shell.o ../shell/shell.c
objs: ${OBJ_FILES}
list_obj:
@echo ${OBJ_FILES}
list_csrc:
@echo ${SRC_CFILES}
list_ssrc:
@echo ${SRC_SFILES}
# Export variables for recursive make calls (such as the library)
export

2683
compile/.deps

File diff suppressed because it is too large Load Diff

1
compile/.vers_num

@ -0,0 +1 @@
280

1
compile/DAC_OUT_PUT1.txt

@ -0,0 +1 @@
****DAC_OUT_PUT1 : Result of conversion DAC channel 1****

1
compile/DAC_OUT_PUT2.txt

@ -0,0 +1 @@
****DAC_OUT_PUT2 : Result of conversion DAC channel 2****

199
compile/Makefile

@ -0,0 +1,199 @@
#########################################################################
# #
# #
# Makefile for STM32 version of the Xinu operating system #
# #
# includes: .deps and .defs #
# #
# #
#########################################################################
COMPILER_ROOT = avr-
PNAME = ATMEGA328P
PLAT = Platform_$(PNAME)
TOPDIR = ..
CC = ${COMPILER_ROOT}gcc
LD = ${COMPILER_ROOT}gcc
OBJCOPY = ${COMPILER_ROOT}objcopy
OBJDUMP = ${COMPILER_ROOT}objdump
QEMU = /home/lechnerm/rafa/xinu/qemu_stm32/arm-softmmu/qemu-system-arm
XINU = $(TOPDIR)/compile/xinu.elf
XINUBIN = $(TOPDIR)/compile/xinu.bin
XINUHEX = $(TOPDIR)/compile/xinu.hex
XINUBOOT = $(TOPDIR)/compile/xinu
BUILDMAKE = $(TOPDIR)/compile/bin/build-make
MKVERS = $(TOPDIR)/compile/bin/mkvers
MAKEDEP = $(CC) -M -MG
DEPSFILE = .deps
DEFSFILE = .defs
VERSIONFILE = version
LDSCRIPT = ld.script
MKVERS = $(TOPDIR)/compile/bin/mkvers
# RAFA -s $(TOPDIR)/device/ram \
REBUILDFLAGS = -s $(TOPDIR)/system debug.c \
#-s $(TOPDIR)/device/gpio \
#-s $(TOPDIR)/device/spi \
-s $(TOPDIR)/device/tty \
#
REBUILDFLAGS = -s $(TOPDIR)/system \
-s $(TOPDIR)/lib \
-s $(TOPDIR)/device/nam \
-s $(TOPDIR)/shell 'xsh_rdstest*'
INCLUDE = -I$(TOPDIR)/include
# RAFA DEFS = -DBSDURG -DVERSION=\""`cat $(VERSIONFILE)`"\"
DEFS = -DVERSION=\""Rafa"\"
# Compiler flags
# CFLAGS = -mcpu=cortex-m3 -mno-unaligned-access -mthumb -fno-builtin -fno-stack-protector -nostdlib -c -Wall -O ${DEFS} ${INCLUDE}
# CFLAGS = -DF_CPU=16000000UL -mmcu=atmega328p -mrelax -fno-builtin -fno-stack-protector -nostdlib -c -Wall -Os ${DEFS} ${INCLUDE}
CFLAGS = -DF_CPU=16000000UL -mmcu=atmega328p -fno-builtin -c -Wall -Os ${DEFS} ${INCLUDE}
SFLAGS = ${INCLUDE}
# Loader flags
# RAFA LDFLAGS = -Wl,--wrap,malloc,--wrap,free,--wrap,realloc,--wrap,fdevopen
# LDFLAGS = -mmcu=atmega328p -nostartfiles -T ld.script -Wl,-Map,xinu.map
LDFLAGS = -mmcu=atmega328p -Wl,-Map,xinu.map
all: xinu
#--------------------------------------------------------------------------------
# Handle generation of a new version string when initialize is recompiled
#--------------------------------------------------------------------------------
newversion:
@echo creating new version
@$(MKVERS) $(PNAME) > version
#--------------------------------------------------------------------------------
# Include generic make targets and rules from the file generated by build-make
#--------------------------------------------------------------------------------
-include $(DEFSFILE)
#--------------------------------------------------------------------------------
# Add files that require special rules and place start.o at the front
#--------------------------------------------------------------------------------
# RAFA quitamos el start.S y start.o porque intentaremos el startup de avr
LD_LIST = binaries/start.o $(filter-out binaries/start.o,$(OBJ_FILES))
# LD_LIST = $(filter-out binaries/start.o,$(OBJ_FILES))
#------------------------------------------------------------
# Rules for files that need special handling
#------------------------------------------------------------
# Define variables for the Configuration file and generated files
CONFFILE = $(TOPDIR)/config/Configuration
CONFH = $(TOPDIR)/include/conf.h
CONFC = $(TOPDIR)/system/conf.c
# Define variables for the config program and its sources
CONFPGM = $(TOPDIR)/config/config
CONFL = $(TOPDIR)/config/config.l
CONFY = $(TOPDIR)/config/config.y
# Set up the required build directory structure
BLDDIRS = binaries
export
#--------------------------------------------------------------------------------
# Specific additional rules and exceptions
#--------------------------------------------------------------------------------
xinu: Makefile rebuild $(BLDDIRS) $(DEFSFILE) $(DEPSFILE) $(CONFH) $(CONFC) $(LD_LIST)
@echo;echo 'Loading object files to produce xinu'
# RAFA original : @$(LD) $(LDFLAGS) $(LD_LIST) -o $(XINU) -L/usr/lib/gcc/arm-none-eabi/6.3.1/ --print-memory-usage
@$(LD) $(LDFLAGS) $(LD_LIST) -o $(XINU)
@echo "Creating Binary..."
@$(OBJCOPY) -O binary $(XINU) $(XINUBIN)
examine-all:
$(OBJDUMP) -D $(XINU) | less
examine-header:
$(OBJDUMP) -x $(XINU) | less
flash:
avr-objcopy -O ihex -R .eeprom $(XINU) $(XINUHEX)
avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 -b 57600 -D -U flash:w:$(XINUHEX):i
# avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 -b 115200 -D -U flash:w:$(FIRMWARE):i
qemu:
$(QEMU) -serial stdio -M stm32-f103c8 -kernel $(XINUBIN)
monitor:
$(QEMU) -monitor stdio -serial stdio -M stm32-f103c8 -kernel $(XINUBIN)
$(BLDDIRS):
@mkdir -p $(BLDDIRS)
objects: $(LD_LIST)
$(CONFH): $(CONFFILE) $(CONFPGM)
@echo making $(CONFH)
@make configure
$(CONFC): $(CONFFILE) $(CONFPGM)
@echo making $(CONFC)
@make configure
$(CONFPGM): $(CONFL) $(CONFY)
@echo making the config program
@make -C $(TOPDIR)/config clean all install
configure:
@echo forcing a rebuild of conf.h and conf.c
@make newversion
@(cd $(TOPDIR)/config; make install)
clean:
@echo removing .o files
@rm -f ${LD_LIST}
@echo removing configuration files ...
@rm -f $(CONFH) $(CONFC)
@(cd $(TOPDIR)/config; make clean)
@echo removing xinu ...
@rm -f $(XINU)
@rm -f $(XINUBIN)
@rm -f $(XINUBOOT)
#--------------------------------------------------------------------------------
# Locations of source directories and exceptions (.c and .[sS] files to exclude)
#--------------------------------------------------------------------------------
$(DEFSFILE):
@rm -f $(DEFSFILE)
@echo "" > $(DEFSFILE)
@make rebuild
$(DEPSFILE):
@rm -f $(DEPSFILE)
@echo "" > $(DEPSFILE)
@make depend
rebuild: $(CONFC)
@echo Rebuilding the $(DEFSFILE) file
@$(BUILDMAKE) $(REBUILDFLAGS) > $(DEFSFILE)
defclean:
rm -f $(DEFSFILE)
echo "" > $(DEFSFILE)
depend: $(DEFSFILE)
@echo;echo Making all dependencies in $(DEPSFILE)
@$(MAKEDEP) ${INCLUDE} ${SRC_FULL} > $(DEPSFILE)
@echo;echo Finished making dependencies
depclean:
rm -f $(DEPSFILE)
echo "" > $(DEPSFILE)
-include $(DEPSFILE)

710
compile/bin/build-make

@ -0,0 +1,710 @@
#!/bin/sh
#########################################################################
# #
# build-make - build entries for a makefile #
# #
# use: build-make dir_spec... #
# #
# where each dir_spec, which specifies one of the source #
# directories to include has the form: #
# #
# -s source_dir_path [pattern...] #
# #
# Build-make generates rules for a Makefile that will compile #
# the source files from the specified set of source directories. #
# Build-make is run in the directory that will hold the Makefile, #
# and assumes .o files will be placed in the ./binaries #
# directory in the same file as the Makefile. #
# #
# #
# A directory specification begins with a -s srgument that is #
# followed by a source directory name (a relative path is #
# recommended, but not required), and a list of zero or more #
# patterns. The patterns are used to specify which files #
# from source directory should be omitted from consideration. #
# Build-make starts by making a list of all C and assembly #
# language files in the directory (i.e. files that match *.c and #
# *.[Ss]). It then uses the set of patterns (if any are present) #
# to decide which of the files to exclude from further #
# processing. A pattern can contain literal characters plus one #
# asterisk, which indicates a wild card match. For example, #
# 'xxx', 'xxx*', '*xxx', 'xxx*yyy' are legal forms of patterns. #
# Note: any pattern argument that contains an asterisk must be #
# enclosed in quotes on the command line to prevent the shell #
# from interpreting it. For example, to omit files that start #
# with 'debug', one would specify: 'debug*' in quotes. Omitting #
# files has two purposes. First, it allows files to be left in #
# the soruce directory that are not normally needed (e.g., #
# debug.c). Second, a programmer can specify a set of files #
# for which standard compilation rules are insufficient. Of #
# course, if a programmer omits a file, the programmer must #
# insert a compilation rule into the Makefile. #
# #
# Build-make does not create a complete Makefile. Instead, #
# build-make writes text output to stdout and allows the #
# programmer to use the output to construct a Makefile. #
# Typically, a programmer runs: #
# #
# build-make > Makedefs #
# #
# and then inserts the line #
# #
# include Makedefs #
# #
# into a Makefile. Doing so allows the Makedefs to be recreated #
# easily if the contents of the source directories change. #
# #
# Build-make generates two variables: SOURCE_FILES that contains #
# a list of all source file names, and OBJECT_FILES that lists #
# all the object files. it also generates a list of rules #
# for generating object files. For example, a rule might #
# be: #
# #
# binaries/aaa.o: ../../system/aaa.c #
# $(CC) $(CFLAGS) -o binaries/aaa.o ../../system/aaa.c #
# #
#########################################################################
MSG1='use is: build-make dir_spec...'
MSG2=' where dir_spec is -s source_dir_path [pattern...]'
#
# Define prefixes shared by this script and the awk program
#
PRE_ERR='+ERROR:'
PRE_DIR='+DIR:'
PRE_OMIT='+OMIT:'
PRE_CFILE='+CFILE:'
PRE_SFILE='+SFILE:'
export PRE_ERR PRE_DIR PRE_OMIT PRE_CFILE PRE_SFILE
TMP1=".,BUILDM1-$$"
TMP2=".,BUILDM2-$$"
trap "rm -f $TMP1 $TMP2; exit" 1 2 3
#
# Parse arguments and generate input to the script below
#
if test $# -lt 2; then
echo "$MSG1" >&2
echo "$MSG2" >&2
exit 1
fi
# iterate through dirspecs
(
> $TMP1
> $TMP2
while test $# -gt 0; do
# parse -s and get directory name
if test $# -lt 2; then
echo "$PRE_ERR"
echo "$MSG1" >&2
echo "$MSG2" >&2
exit 1
fi
case "x$1" in
x-s) DIR="$2"
# verify that directory exists
if test -d $DIR; then
echo "$PRE_DIR$DIR"
else
echo "$PRE_ERR"
echo "cannot find a source directory named $DIR" >&2
exit 1
fi
shift; shift
;;
*) echo 'expecting -s at start of directory specification' >&2
echo "$PRE_ERR"
echo "$MSG1" >&2
echo "$MSG2" >&2
;;
esac
#
# See if DIR contains any .c or .[sS] files
#
if test "x$DIR" = "x."; then
CFILES=`ls *.c 2>$TMP1`
SFILES=`ls *.[sS] 2>$TMP2`
else
CFILES=`ls $DIR/*.c 2>$TMP1`
SFILES=`ls $DIR/*.[sS] 2>$TMP2`
fi
if test -s $TMP1 -a -s $TMP2; then
(echo;echo "Warning: directory $DIR does not contain any .c or .[sS] files to compile";echo) >&2
fi
rm -f $TMP1 $TMP2
# arguments up to the next -s as patterns that specify omitted files
LOOKING=true
while $LOOKING; do
if test $# -eq 0; then
LOOKING=false
elif test "x$1" = "x-s"; then
LOOKING=false
else
echo "$PRE_OMIT$1"
shift
fi
done
# output .s and .S files for this directory
if test "x$SFILES" != "x"; then
for i in $SFILES; do
echo "$PRE_SFILE$i"
done
fi
# output .c files for this directory
if test "x$CFILES" != "x"; then
for i in $CFILES; do
echo "$PRE_CFILE$i"
done
fi
done
) |
gawk '
#########################################################################
# #
# #
# Start of awk script #
# #
# #
#########################################################################
####################
#
# function ftmlist - format a list of file names
#
# args are: number of names, array of names, maximum name length,
# directory name, prefix to use
#
####################
function fmtlist(n,items,maxl,dname, pfix) {
if (n <= 0) {
return;
}
if (doneheading == 0) {
printf("\n\n%s\n%s\n%sDirectory %s\n%s\n%s\n",hdr4, hdr5, hdr6, dname, hdr5, hdr4);
doneheading = 1;
}
fmt2 = sprintf("\n%%-%ds\\\n",maxwid-1);
printf(fmt2, pfix " =");
namwid = maxl + 2;
#
# compute number of names per line allowing 2 blanks between them
# and not taking more than actwid characters
#
nperline = int( (actwid+2)/(maxl+2) );
extrabl = actwid-(nperline*maxl + 2*(nperline-1))+1;
cnt = 1;
fmt = sprintf("%%-%ds",maxl);
for (i=1; i<=n ; i++) {
if (cnt > nperline) {
for (b=1; b<=extrabl; b++) {
printf(" ");
}
printf("\\\n");
cnt = 1;
}
if (cnt == 1) {
printf("%s", tb);
} else {
printf(" ");
}
printf(fmt, items[i]);
cnt++;
}
printf("\n");
return;
}
####################
#
# function isomitted - check a file name against the list of omitted patters
# for the current directory and report 1 if the file
# name is omitted
#
# arg: file name to check
#
# globals used: nomits, omits[] list of omitted patterns (1 through nomits)
#
####################
function isomitted(io_fname) {
io_flen = length(io_fname);
#
# Iterate through all omit patterns for the current directory
#
for (io_j=1; io_j <= nomits; io_j++) {
# Get pattern to check
io_omit = omits[io_j];
# length of omit pattern
io_olen = length(io_omit);
# Find where "*" occurs in the pattern and set prefix length
io_plen = index(io_omit, "*") - 1;
if (io_plen < 0) { # No * in the pattern, so check exact match
if (io_fname == io_omit) {
return 1;
} else {
continue;
}
}
# At least one * occurs in the pattern
if (io_olen == 1) { # Pattern is just a *, so omit everything
return 1;
}
if (io_plen > 1) { # if fixed prefix exists, check for match
# A file name shorter than the prefix is not omitted
if (io_flen < io_plen) {
continue;
}
# If prefix does not match, name is not omitted
if ( substr(io_omit, 1, io_plen) != substr(io_fname, 1, io_plen) ) {
continue;
}
}
# Prefix has matched; check suffix
io_slen = io_olen - io_plen -1;
if (io_slen <= 0) { # If no suffix, pattern matches
return 1;
}
# A file name shorter than the suffix is not omitted
if (io_flen < io_slen) {
continue;
}
# If suffix in omit pattern exactly matches the suffix of the
# file name, this file name is omitted
if ( substr(io_omit, io_olen - (io_slen - 1)) == \
substr(io_fname, length(io_fname) - (io_slen - 1)) ) {
return 1;
}
}
# The file name does not match any omitted pattern, so keep it
return 0;
}
####################
#
# getbasename - extract the basename from a path name and return it
#
# arg: path name
#
####################
function getbasename(gb_path) {
for (gb_pos = length(gb_path); gb_pos > 0; gb_pos--) {
if (substr(gb_path, gb_pos, 1) == "/") {
break;
}
}
if (gb_pos > 0) {
return substr(gb_path, gb_pos+1);
} else {
return gb_path;
}
}
####################
#
# Initialize variables for the awk script
#
####################
BEGIN {
ndirs = 0; # Number of directories found so far
maxwid = 81; # Maximum width of formatted line
actwid = maxwid - 10; # Actual width for names (line width minus 8 for tab indent and
# 2 for " \" at the end of the line)
tb = " "; # Tab character
plen_err = length("'$PRE_ERR'");
plen_dir = length("'$PRE_DIR'");
plen_omt = length("'$PRE_OMIT'");
plen_cfl = length("'$PRE_CFILE'");
plen_sfl = length("'$PRE_SFILE'");
hdr1 = "#-------------------------------------------------------------------------------#";
hdr2 = "# #";
hdr3 = "# Definitions generated by build-make on '"`date`"' #";
hdr4 = "#------------------------------------------------------------------";
hdr5 = "#";
hdr6 = "# ";
hdr7 = "# Rules For Generating Object Files #";
hdr8 = "# Rules for files in directory ";
msg1 = "SRC_CFILES =";
msg2 = "SRC_SFILES =";
msg3 = "OBJ_FILES =";
}
#
# Skip blank lines in input
#
/^ *$/ {
next;
}
#
# Handle errors
#
/^\'${PRE_ERR}'/ {
exit(1);
}
#
# Start a new directory
#
/^\'$PRE_DIR'/ {
ndirs++;
dirs[ndirs] = substr($0,plen_dir+1);
# Initialize counts for this directory
ncfiles[ndirs] = 0;
nsfiles[ndirs] = 0;
nomits = 0;
next;
}
#
# Collect list of omitted files for this directory (must occur in the input before
# any C or S files for the directory)
#
/^\'$PRE_OMIT'/ {
nomits++;
omits[nomits] = substr($0,plen_omt+1);
next;
}
#
# Handle a C file from the current directory
#
/^\'$PRE_CFILE'/ {
fullname = substr($0,plen_cfl+1);
basename = getbasename(fullname);
# Skip omitted files
if (isomitted(basename) > 0) {
next;
}
ncfiles[ndirs]++;
cpath[ndirs "%" ncfiles[ndirs]] = fullname;
cfile[ndirs "%" ncfiles[ndirs]] = basename;
next;
}
#
# Handle as S file from the current directory
#
/^\'$PRE_SFILE'/ {
fullname = substr($0,plen_sfl+1);
basename = getbasename(fullname);
# Skip omitted files
if (isomitted(basename) > 0) {
next;
}
nsfiles[ndirs]++;
spath[ndirs "%" nsfiles[ndirs]] = fullname;
sfile[ndirs "%" nsfiles[ndirs]] = basename;
next;
}
#
# Any other input line is unexpected
#
{
print "Error: unexpected input line ->", $0;
exit 1;
}
END {
#################################################################
# #
# Do all the work of formatting and printing the makefile #
# rules. Start by printing an initial comment block and the #
# variable initializtion statements. #
# #
#################################################################
printf("%s\n%s\n%s\n%s\n%s\n\n",hdr1, hdr2, hdr3, hdr2, hdr1);
printf("%s\n%s\n\n",msg1, msg2, msg3);
totlen = 0; # max over valid source file names in all directories
#################################################################
# #
# Iterate over all directories and generate a unique prefix #
# to be used on make variables for each directory #
# #
#################################################################
totlen = 0; # max file name length across all directories
for (d=1; d<=ndirs; d++) {
# Generate a unique variable name prefix for this directory
dirpath = dirs[d];
strt = 1;
str = toupper(dirpath);
finish = length(str);
ch = substr(str,strt,1);
while ( (ch == ".") || (ch == "/") ) {
strt++;
if (strt > finish) {
break;
}
ch = substr(str,strt,1);
}
if (strt > finish) {
if (substr(str,1,1) == ".") {
prefix = "DOT";
} else {
prefix = "SLASH";
}
for (i=2; i<=finish; i++) {
if (substr(str,i,1) == ".") {
prefix = prefix "_DOT";
} else {
prefix = prefix "_SLASH";
}
}
} else {
prefix = "";
for (i=strt; i<=finish; i++) {
ch = substr(str,i,1);
if (ch == "/") {
prefix = prefix "_";
} else {
prefix = prefix ch;
}
}
}
pref[d] = prefix;
doneheading = 0;
#
# Compute the maximum length of a file name in this directory
# and update the max length across all directories
#
maxlen = 0; # max file name length for this directory
# Check S files first
for (i = 1; i <= nsfiles[d]; i++) {
srcsfiles[i] = sfile[d "%" i]
l = length(srcsfiles[i]);
if (l > maxlen) {
maxlen = l;
}
}
if (maxlen > totlen) { # update global max across all directories
totlen = maxlen;
}
# Check C files
for (i = 1; i <= ncfiles[d]; i++) {
srccfiles[i] = cfile[d "%" i]
l = length(srccfiles[i]);
if (l > maxlen) {
maxlen = l;
}
}
if (maxlen > totlen) { # update global max across all directories
totlen = maxlen;
}
# Format the list of S files for this directory
fmtlist(nsfiles[d], srcsfiles, maxlen, dirs[d], pref[d] "_SFILES");
# Format the list of C files for this directory
fmtlist(ncfiles[d], srccfiles, maxlen, dirs[d], pref[d] "_CFILES");
printf("\n");
#
# Generate assignments for Makefile variables
#
nasn = 0;
#
# Generate assignments for variables SRC_CFILES and SRC_SFILES
#
if (ncfiles[d] > 0) {
nasn++;
asnl[nasn] = "SRC_CFILES";
asnr[nasn] = sprintf("+= ${%s_CFILES}", pref[d]);
}
if (nsfiles[d] > 0) {
nasn++;
asnl[nasn] = "SRC_SFILES";
asnr[nasn] = sprintf("+= ${%s_SFILES}", pref[d]);
}
#
# Generate assignments for variables prefix_CFULL and prefix_SFULL
#
if (ncfiles[d] > 0) {
nasn++;
asnl[nasn] = sprintf("%s_CFULL", prefix);
asnr[nasn] = sprintf("+= ${%s_CFILES:%%=%s/%%}", pref[d], dirs[d]);
}
if (nsfiles[d] > 0) {
nasn++;
asnl[nasn] = sprintf("%s_SFULL", prefix);
asnr[nasn] = sprintf("+= ${%s_SFILES:%%=%s/%%}", pref[d], dirs[d]);
}
#
# Generate assignments for variables SRC_CFULL and SRC_SFULL
#
if (ncfiles[d] > 0) {
nasn++;
asnl[nasn] = "SRC_CFULL";
asnr[nasn] = sprintf("+= ${%s_CFULL}", pref[d]);
}
if (nsfiles[d] > 0) {
nasn++;
asnl[nasn] = "SRC_SFULL";
asnr[nasn] = sprintf("+= ${%s_SFULL}", pref[d]);
}
wid = 0;
for (i=1; i<=nasn; i++) {
n = length(asnl[i]);
if (n > wid) {
wid = n;
}
}
fmt3 = sprintf("%%-%ds %%s\n", wid);
for (i=1; i<=nasn; i++) {
printf(fmt3, asnl[i], asnr[i]);
}
}
printf("\n\n%s\n%s\n%s\n%s\n%s\n\n", hdr1, hdr2, hdr7, hdr2, hdr1);
printf("OBJ_TMP = ${patsubst %%.s,%%.o,$(SRC_SFILES)} # substitute .s => .o\n");
printf("OBJ_SFILES = ${patsubst %%.S,%%.o,$(OBJ_TMP)} # substitute .S => .o\n");
printf("OBJ_CFILES = ${patsubst %%.c,%%.o,$(SRC_CFILES)} # substitute .c => .o\n");
printf("OBJ_LIST = ${OBJ_CFILES} ${OBJ_SFILES}\n");
printf("OBJ_FILES = ${OBJ_LIST:%%=binaries/%%}\n");
printf("SRC_FULL = ${SRC_CFULL} ${SRC_SFULL}\n");
fmt4c = sprintf("%%-%ds%%s\n\t${CC} ${CFLAGS} -o %%s %%s\n",9+totlen+3);
fmt4s = sprintf("%%-%ds%%s\n\t${CC} ${CFLAGS} -o %%s %%s\n",9+totlen+3);
for (d=1; d<=ndirs; d++) {
needheadings = 1;
# print dependencies for .s files
for (i = 1; i <= nsfiles[d]; i++) {
if (needheadings > 0) {
printf("\n%s\n%s%s\n%s\n\n", hdr4, hdr8, dirs[d], hdr4);
needheadings = 0;
}
fname = sfile[d "%" i];
tmpobj = "binaries/" substr(fname, 1, length(fname)-2) ".o";
tmpsrc = dirs[d] "/" fname;
printf(fmt4s, tmpobj ":", tmpsrc, tmpobj, tmpsrc);
}
# print dependencies for .c files
for (i = 1; i <= ncfiles[d]; i++) {
if (needheadings > 0) {
printf("\n%s\n%s%s\n%s\n\n", hdr4, hdr8, dirs[d], hdr4);
needheadings = 0;
}
fname = cfile[d "%" i];
tmpobj = "binaries/" substr(fname, 1, length(fname)-2) ".o";
tmpsrc = dirs[d] "/" fname;
printf(fmt4c, tmpobj ":", tmpsrc, tmpobj, tmpsrc);
}
}
printf("\nobjs: ${OBJ_FILES}\n");
printf("\nlist_obj:\n\t@echo ${OBJ_FILES}\n");
printf("\nlist_csrc:\n\t@echo ${SRC_CFILES}\n");
printf("\nlist_ssrc:\n\t@echo ${SRC_SFILES}\n");
printf("\n# Export variables for recursive make calls (such as the library)\n\nexport\n\n");
} '

27
compile/bin/mkvers

@ -0,0 +1,27 @@
#!/bin/sh
#
# Generate a new version string to be printed at startup
#
# Use is: mkvers platform_name
VERS_NUM_FILE=.vers_num
case $# in
1) PLAT="$1"
;;
*) echo 'use is: mkvers platform_name' >&2
exit 1
;;
esac
if test -s $VERS_NUM_FILE; then
OLD_VERS=`cat $VERS_NUM_FILE`
VERS=`expr $OLD_VERS + 1`
else
VERS=1
fi
echo $VERS > $VERS_NUM_FILE
if test "x$USER" = "x"; then
USER=`who am i | sed 's/ .*//'`
fi
echo "Xinu for $PLAT -- version #$VERS ($USER) `date`"

BIN
compile/binaries/getchar.o

Binary file not shown.

BIN
compile/binaries/putchar.o

Binary file not shown.

BIN
compile/binaries/qsort.o

Binary file not shown.

189
compile/original/Makefile.orig

@ -0,0 +1,189 @@
#########################################################################
# #
# #
# Makefile for STM32 version of the Xinu operating system #
# #
# includes: .deps and .defs #
# #
# #
#########################################################################
COMPILER_ROOT = avr-
PNAME = ATMEGA328P
PLAT = Platform_$(PNAME)
TOPDIR = ..
CC = ${COMPILER_ROOT}gcc
LD = ${COMPILER_ROOT}gcc
OBJCOPY = ${COMPILER_ROOT}objcopy
OBJDUMP = ${COMPILER_ROOT}objdump
QEMU = /home/lechnerm/rafa/xinu/qemu_stm32/arm-softmmu/qemu-system-arm
XINU = $(TOPDIR)/compile/xinu.elf
XINUBIN = $(TOPDIR)/compile/xinu.bin
XINUBOOT = $(TOPDIR)/compile/xinu
BUILDMAKE = $(TOPDIR)/compile/bin/build-make
MKVERS = $(TOPDIR)/compile/bin/mkvers
MAKEDEP = $(CC) -M -MG
DEPSFILE = .deps
DEFSFILE = .defs
VERSIONFILE = version
# RAFA LDSCRIPT = ld.script
MKVERS = $(TOPDIR)/compile/bin/mkvers
REBUILDFLAGS = -s $(TOPDIR)/system debug.c \
-s $(TOPDIR)/lib \
-s $(TOPDIR)/device/tty \
-s $(TOPDIR)/device/nam \
# RAFA -s $(TOPDIR)/device/ram \
-s $(TOPDIR)/device/gpio \
-s $(TOPDIR)/device/spi \
#
-s $(TOPDIR)/shell 'xsh_rdstest*'
INCLUDE = -I$(TOPDIR)/include
DEFS = -DBSDURG -DVERSION=\""`cat $(VERSIONFILE)`"\"
# Compiler flags
# CFLAGS = -mcpu=cortex-m3 -mno-unaligned-access -mthumb -fno-builtin -fno-stack-protector -nostdlib -c -Wall -O ${DEFS} ${INCLUDE}
CFLAGS = -DF_CPU=16000000UL -mmcu=atmega328p -mrelax -fno-builtin -fno-stack-protector -nostdlib -c -Wall -Os ${DEFS} ${INCLUDE}
SFLAGS = ${INCLUDE}
# Loader flags
# RAFA LDFLAGS = -dn -m armelf -Map xinu.map -T ld.script
LDFLAGS = -Wl,--wrap,malloc,--wrap,free,--wrap,realloc,--wrap,fdevopen
all: xinu
#--------------------------------------------------------------------------------
# Handle generation of a new version string when initialize is recompiled
#--------------------------------------------------------------------------------
newversion:
@echo creating new version
@$(MKVERS) $(PNAME) > version
#--------------------------------------------------------------------------------
# Include generic make targets and rules from the file generated by build-make
#--------------------------------------------------------------------------------
-include $(DEFSFILE)
#--------------------------------------------------------------------------------
# Add files that require special rules and place start.o at the front
#--------------------------------------------------------------------------------
# RAFA quitamos el start.S y start.o porque intentaremos el startup de avr
# RAFA LD_LIST = binaries/start.o $(filter-out binaries/start.o,$(OBJ_FILES))
LD_LIST = $(filter-out binaries/start.o,$(OBJ_FILES))
#------------------------------------------------------------
# Rules for files that need special handling
#------------------------------------------------------------
# Define variables for the Configuration file and generated files
CONFFILE = $(TOPDIR)/config/Configuration
CONFH = $(TOPDIR)/include/conf.h
CONFC = $(TOPDIR)/system/conf.c
# Define variables for the config program and its sources
CONFPGM = $(TOPDIR)/config/config
CONFL = $(TOPDIR)/config/config.l
CONFY = $(TOPDIR)/config/config.y
# Set up the required build directory structure
BLDDIRS = binaries
export
#--------------------------------------------------------------------------------
# Specific additional rules and exceptions
#--------------------------------------------------------------------------------
xinu: Makefile rebuild $(BLDDIRS) $(DEFSFILE) $(DEPSFILE) $(CONFH) $(CONFC) $(LD_LIST)
@echo;echo 'Loading object files to produce xinu'
# RAFA original : @$(LD) $(LDFLAGS) $(LD_LIST) -o $(XINU) -L/usr/lib/gcc/arm-none-eabi/6.3.1/ --print-memory-usage
@$(LD) $(LDFLAGS) -T ld.script $(LD_LIST) -o $(XINU)
@echo "Creating Binary..."
@$(OBJCOPY) -O binary $(XINU) $(XINUBIN)
examine-all:
$(OBJDUMP) -D $(XINU) | less
examine-header:
$(OBJDUMP) -x $(XINU) | less
flash:
stm32flash -w $(XINUBIN) -v /dev/ttyUSB0
qemu:
$(QEMU) -serial stdio -M stm32-f103c8 -kernel $(XINUBIN)
monitor:
$(QEMU) -monitor stdio -serial stdio -M stm32-f103c8 -kernel $(XINUBIN)
$(BLDDIRS):
@mkdir -p $(BLDDIRS)
objects: $(LD_LIST)
$(CONFH): $(CONFFILE) $(CONFPGM)
@echo making $(CONFH)
@make configure
$(CONFC): $(CONFFILE) $(CONFPGM)
@echo making $(CONFC)
@make configure
$(CONFPGM): $(CONFL) $(CONFY)
@echo making the config program
@make -C $(TOPDIR)/config clean all install
configure:
@echo forcing a rebuild of conf.h and conf.c
@make newversion
@(cd $(TOPDIR)/config; make install)
clean:
@echo removing .o files
@rm -f ${LD_LIST}
@echo removing configuration files ...
@rm -f $(CONFH) $(CONFC)
@(cd $(TOPDIR)/config; make clean)
@echo removing xinu ...
@rm -f $(XINU)
@rm -f $(XINUBIN)
@rm -f $(XINUBOOT)
#--------------------------------------------------------------------------------
# Locations of source directories and exceptions (.c and .[sS] files to exclude)
#--------------------------------------------------------------------------------
$(DEFSFILE):
@rm -f $(DEFSFILE)
@echo "" > $(DEFSFILE)
@make rebuild
$(DEPSFILE):
@rm -f $(DEPSFILE)
@echo "" > $(DEPSFILE)
@make depend
rebuild: $(CONFC)
@echo Rebuilding the $(DEFSFILE) file
@$(BUILDMAKE) $(REBUILDFLAGS) > $(DEFSFILE)
defclean:
rm -f $(DEFSFILE)
echo "" > $(DEFSFILE)
depend: $(DEFSFILE)
@echo;echo Making all dependencies in $(DEPSFILE)
@$(MAKEDEP) ${INCLUDE} ${SRC_FULL} > $(DEPSFILE)
@echo;echo Finished making dependencies
depclean:
rm -f $(DEPSFILE)
echo "" > $(DEPSFILE)
-include $(DEPSFILE)

1
compile/original/flash.sh

@ -0,0 +1 @@
~/rafa/stm32flash/stm32flash -w xinu.bin -S 0x8000000 -v -g 0x8000000 -b 115200 /dev/ttyUSB0

135
compile/original/ld.script

@ -0,0 +1,135 @@
/* Linker script for ATMEL(R) AVR(R) ATmega328P. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
/* The beginning and end of the program ROM area. */
/* Leave 4 bytes for the 32-bit checksum plus 0x10 extra bytes free. */
_rom_begin = 0x00000000;
_rom_end = 0x00007FEC;
/* The beginning and end (i.e., top) of the stack */
/* Set up a stack with a size of (1/2)K */
_stack_begin = 0x800500;
_stack_end = 0x8008FF; /* RAFA, en atmega328 el fin de la RAM */
/* The end of the 2K RAM stack */
__initial_stack_pointer = 0x8008FF;
MEMORY
{
ROM(rx) : ORIGIN = 0, LENGTH = 32K
RAM(rw!x) : ORIGIN = 0x800100, LENGTH = 2K
}
SECTIONS
{
. = 0x0;
. = ALIGN(2);
.text :
{
/* RAFA _*/
text = ABSOLUTE(.); /* text: beginning of text segment */
*(.vectors)
KEEP(*(.vectors))
/*Init sections were here*/
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
*(.init0) /* Start here after reset. */
__ctors_end = .;
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.def_isr)
KEEP(*(.def_isr))
*(.progmem*)
. = ALIGN(2);
*(.text)
. = ALIGN(2);
*(.text*)
. = ALIGN(2);
etext = ABSOLUTE(.) ; /* etext: end of text */
} > ROM
.text :
{
. = ALIGN(0x10);
} > ROM = 0xAAAA
.= 0x800100;
. = ALIGN(2);
/* The ROM-to-RAM initialized data section */
.data :
{
data = ABSOLUTE(.); /* data: beginning of data segment */
__data = ABSOLUTE(.); /* data: beginning of data segment */
_data_begin = .;
*(.data)
. = ALIGN(2);
KEEP (*(.data))
*(.data*)
. = ALIGN(2);
KEEP (*(.data*))
*(.rodata) /* Do *NOT* move this! Include .rodata here if gcc is used with -fdata-sections. */
. = ALIGN(2);
KEEP (*(.rodata))
*(.rodata*)
. = ALIGN(2);
KEEP (*(.rodata*))
__data_end = .;
__data_start = .;
__data_load_start = .;
__bss_start = .;
} > RAM AT > ROM
/* The uninitialized (zero-cleared) data section */
.bss :
{
__bss = ABSOLUTE(.); /* bss: beginning of bss segment */
*(.bss)
. = ALIGN(2);
KEEP (*(.bss))
*(.bss*)
. = ALIGN(2);
KEEP (*(.bss*))
__bss_end = ABSOLUTE(.); /* _end: end of image */
} > RAM
_rom_data_begin = LOADADDR(.data);
__data_load = LOADADDR(.data);
}

135
compile/original/ld.script.avr

@ -0,0 +1,135 @@
/* Linker script for ATMEL(R) AVR(R) ATmega328P. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
/* The beginning and end of the program ROM area. */
/* Leave 4 bytes for the 32-bit checksum plus 0x10 extra bytes free. */
_rom_begin = 0x00000000;
_rom_end = 0x00007FEC;
/* The beginning and end (i.e., top) of the stack */
/* Set up a stack with a size of (1/2)K */
_stack_begin = 0x800500;
_stack_end = 0x8008FF; /* RAFA, en atmega328 el fin de la RAM */
/* The end of the 2K RAM stack */
__initial_stack_pointer = 0x8008FF;
MEMORY
{
ROM(rx) : ORIGIN = 0, LENGTH = 32K
RAM(rw!x) : ORIGIN = 0x800100, LENGTH = 2K
}
SECTIONS
{
. = 0x0;
/* RAFA . = ALIGN(2); */
/* ISR vectors */
.isr_vector :
{
*(.isr_vector)
. = ALIGN(0x10);
KEEP(*(.isr_vector))
} > ROM = 0xAAAA
/* Startup code */
.startup :
{
*(.startup)
. = ALIGN(0x10);
KEEP(*(.startup))
} > ROM = 0xAAAA
/* Program code (text), read-only data and static ctors */
.text :
{
/* RAFA _*/
text = ABSOLUTE(.); /* text: beginning of text segment */
__muluhisi3 = .;
start = .;
__do_copy_data = .;
__do_clear_bss = .;
_/* _data_end = .; */
__data_load_start = .;
__bss_end = .;
__bss_start = .;
__data_start = .;
/* FIN DE RAFA */
_ctors_begin = .;
*(.ctors)
. = ALIGN(2);
KEEP (*(SORT(.ctors)))
_ctors_end = .;
*(.progmem*)
. = ALIGN(2);
*(.trampolines*)
. = ALIGN(2);
*(.text)
. = ALIGN(2);
*(.text*)
. = ALIGN(2);
etext = ABSOLUTE(.) ; /* etext: end of text */
} > ROM
.text :
{
. = ALIGN(0x10);
} > ROM = 0xAAAA
.= 0x800100;
. = ALIGN(2);
/* The ROM-to-RAM initialized data section */
.data :
{
data = ABSOLUTE(.); /* data: beginning of data segment */
_data_begin = .;
*(.data)
/* rafa . = ALIGN(2); */
. = ALIGN(1);
KEEP (*(.data))
*(.data*)
/* RAafa . = ALIGN(2); todos los demas tambien */
. = ALIGN(1);
KEEP (*(.data*))
*(.rodata) /* Do *NOT* move this! Include .rodata here if gcc is used with -fdata-sections. */
. = ALIGN(1);
KEEP (*(.rodata))
*(.rodata*)
. = ALIGN(1);
KEEP (*(.rodata*))
_data_end = .;
edata = ABSOLUTE(.) ; /* edata: end of data */
} > RAM AT > ROM
/* The uninitialized (zero-cleared) data section */
.bss :
{
bss = ABSOLUTE(.); /* bss: beginning of bss segment */
_bss_begin = .;
*(.bss)
. = ALIGN(1);
KEEP (*(.bss))
*(.bss*)
. = ALIGN(1);
KEEP (*(.bss*))
_bss_end = .;
ebss = ABSOLUTE(.) ; /* ebss: end of bss */
end = ABSOLUTE(.); /* end: end of image */
_end = ABSOLUTE(.); /* _end: end of image */
} > RAM
_rom_data_begin = LOADADDR(.data);
}

105
compile/original/ld.script.avr.baremetal

@ -0,0 +1,105 @@
/* Linker script for ATMEL(R) AVR(R) ATmega328P. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
/* The beginning and end of the program ROM area. */
/* Leave 4 bytes for the 32-bit checksum plus 0x10 extra bytes free. */
_rom_begin = 0x00000000;
_rom_end = 0x00007FEC;
/* The beginning and end (i.e., top) of the stack */
/* Set up a stack with a size of (1/2)K */
_stack_begin = 0x800500;
_stack_end = 0x800800;
/* The end of the 2K RAM stack */
__initial_stack_pointer = 0x800800;
MEMORY
{
ROM(rx) : ORIGIN = 0, LENGTH = 32K - 0x14
RAM(rw!x) : ORIGIN = 0x800100, LENGTH = 0x0800
}
SECTIONS
{
. = 0x0;
. = ALIGN(2);
/* ISR vectors */
.isr_vector :
{
*(.isr_vector)
. = ALIGN(0x10);
KEEP(*(.isr_vector))
} > ROM = 0xAAAA
/* Startup code */
.startup :
{
*(.startup)
. = ALIGN(0x10);
KEEP(*(.startup))
} > ROM = 0xAAAA
/* Program code (text), read-only data and static ctors */
.text :
{
_ctors_begin = .;
*(.ctors)
. = ALIGN(2);
KEEP (*(SORT(.ctors)))
_ctors_end = .;
*(.progmem*)
. = ALIGN(2);
*(.trampolines*)
. = ALIGN(2);
*(.text)
. = ALIGN(2);
*(.text*)
. = ALIGN(2);
} > ROM
.text :
{
. = ALIGN(0x10);
} > ROM = 0xAAAA
.= 0x800100;
. = ALIGN(2);
/* The ROM-to-RAM initialized data section */
.data :
{
_data_begin = .;
*(.data)
. = ALIGN(2);
KEEP (*(.data))
*(.data*)
. = ALIGN(2);
KEEP (*(.data*))
*(.rodata) /* Do *NOT* move this! Include .rodata here if gcc is used with -fdata-sections. */
. = ALIGN(2);
KEEP (*(.rodata))
*(.rodata*)
. = ALIGN(2);
KEEP (*(.rodata*))
_data_end = .;
} > RAM AT > ROM
/* The uninitialized (zero-cleared) data section */
.bss :
{
_bss_begin = .;
*(.bss)
. = ALIGN(2);
KEEP (*(.bss))
*(.bss*)
. = ALIGN(2);
KEEP (*(.bss*))
_bss_end = .;
} > RAM
_rom_data_begin = LOADADDR(.data);
}

149
compile/original/ld.script.avr2

@ -0,0 +1,149 @@
/* Linker script for ATMEL(R) AVR(R) ATmega328P. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
/* The beginning and end of the program ROM area. */
/* Leave 4 bytes for the 32-bit checksum plus 0x10 extra bytes free. */
_rom_begin = 0x00000000;
_rom_end = 0x00007FEC;
/* The beginning and end (i.e., top) of the stack */
/* Set up a stack with a size of (1/2)K */
_stack_begin = 0x800500;
_stack_end = 0x8008FF; /* RAFA, en atmega328 el fin de la RAM */
/* The end of the 2K RAM stack */
__initial_stack_pointer = 0x8008FF;
MEMORY
{
ROM(rx) : ORIGIN = 0, LENGTH = 32K
RAM(rw!x) : ORIGIN = 0x800100, LENGTH = 2K
}
SECTIONS
{
. = 0x0;
. = ALIGN(2);
.text :
{
/* RAFA _*/
text = ABSOLUTE(.); /* text: beginning of text segment */
*(.vectors)
KEEP(*(.vectors))
/*Init sections were here*/
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
*(.init0) /* Start here after reset. */
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.def_isr)
KEEP(*(.def_isr))
__muluhisi3 = .;
start = .;
__do_copy_data = .;
__do_clear_bss = .;
_/* _data_end = .; */
__data_load_start = .;
__bss_end = .;
__bss_start = .;
__data_start = .;
/* FIN DE RAFA */
_ctors_begin = .;
*(.ctors)
. = ALIGN(2);
KEEP (*(SORT(.ctors)))
_ctors_end = .;
*(.progmem*)
. = ALIGN(2);
*(.trampolines*)
. = ALIGN(2);
*(.text)
. = ALIGN(2);
*(.text*)
. = ALIGN(2);
etext = ABSOLUTE(.) ; /* etext: end of text */
} > ROM
.text :
{
. = ALIGN(0x10);
} > ROM = 0xAAAA
.= 0x800100;
. = ALIGN(2);
/* The ROM-to-RAM initialized data section */
.data :
{
data = ABSOLUTE(.); /* data: beginning of data segment */
_data_begin = .;
*(.data)
. = ALIGN(2);
KEEP (*(.data))
*(.data*)
. = ALIGN(2);
KEEP (*(.data*))
*(.rodata) /* Do *NOT* move this! Include .rodata here if gcc is used with -fdata-sections. */
. = ALIGN(2);
KEEP (*(.rodata))
*(.rodata*)
. = ALIGN(2);
KEEP (*(.rodata*))
_data_end = .;
__data_end = .;
edata = ABSOLUTE(.) ; /* edata: end of data */
} > RAM AT > ROM
/* The uninitialized (zero-cleared) data section */
.bss :
{
bss = ABSOLUTE(.); /* bss: beginning of bss segment */
_bss_begin = .;
*(.bss)
. = ALIGN(2);
KEEP (*(.bss))
*(.bss*)
. = ALIGN(2);
KEEP (*(.bss*))
_bss_end = .;
ebss = ABSOLUTE(.) ; /* ebss: end of bss */
end = ABSOLUTE(.); /* end: end of image */
_end = ABSOLUTE(.); /* _end: end of image */
} > RAM
_rom_data_begin = LOADADDR(.data);
}

55
compile/original/ld.script.stm32

@ -0,0 +1,55 @@
/* Xinu for STM32
*
* Original license applies
* Modifications for STM32 by Robin Krens
* Please see LICENSE and AUTHORS
*
* $LOG$
* 2019/11/11 - ROBIN KRENS
* Initial version
*
* $DESCRIPTION$
*
* */
/* OUTPUT_ARCH(arm) */
ENTRY(start)
physbase = 0x08000000;
MEMORY
{
/* FLASH (xr) : ORIGIN = 0x08000000, LENGTH = 512K */
FLASH (xr) : ORIGIN = 0x8000000, LENGTH = 128K
/* SRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K */
SRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
}
SECTIONS
{
. = 0x0; /* Image starts here */
.text : ALIGN(4) {
text = ABSOLUTE(.); /* text: beginning of text segment */
*(.text .text.*) /* asm text, then C text */
*(.rodata .rodata.*) /* asm and C read-only data */
etext = ABSOLUTE(.) ; /* etext: end of text */
}
. = 0x20000000;
.data : AT(etext)
{
data = ABSOLUTE(.); /* data: beginning of data segment */
*(.data .data.*)
edata = ABSOLUTE(.) ; /* edata: end of data */
}
.bss ALIGN(4) :
{
bss = ABSOLUTE(.); /* bss: beginning of bss segment */
*(.bss .bss.*)
*(COMMON) /* extra sections that are common */
ebss = ABSOLUTE(.) ; /* ebss: end of bss */
. = ALIGN(8); */
end = ABSOLUTE(.); /* end: end of image */
_end = ABSOLUTE(.); /* _end: end of image */
. = ALIGN(8);
}
}

1
compile/version

@ -0,0 +1 @@
Xinu for ATMEGA328P -- version #280 (lechnerm) dom may 17 23:40:51 -03 2020

1108
compile/xinu.hex

File diff suppressed because it is too large Load Diff

1332
compile/xinu.map

File diff suppressed because it is too large Load Diff

119
config/Configuration

@ -0,0 +1,119 @@
/************************************************************************/
/* */
/* Configuration - Xinu device configuration specification file */
/* */
/* This file becomes input to the config program, which generates */
/* conf.h and conf.c */
/* */
/* Entries for a device specify the functions that handle each of the */
/* high-level I/O operations as follows: */
/* */
/* -i init -o open -c close */
/* -r read -w write -s seek */
/* -g getc -p putc -n control */
/* -intr int_hndlr -csr csr -irq irq */
/* */
/************************************************************************/
/* Type Declarations for both real- and pseudo- device types */
/* type of a null device */
null:
on nothing
-i ionull -o ionull -c ionull
-r ionull -g ionull -p ionull
-w ionull -s ioerr
/* type of a gpio device */
/* RAFA
gpio:
on standard_gpio
-i gpioinit -o ionull -c ionull
-r gpioread -g ionull -p ionull
-w gpiowrite -s ioerr -n gpiocontrol
-intr gpiohandler
FIN DE RAFA */
/* type of a tty device */
tty:
/* RAFA
on uart
-i ttyinit -o ionull -c ionull
-r ttyread -g ttygetc -p ttyputc
-w ttywrite -s ioerr -n ttycontrol
-intr ttyhandler
FIN DE RAFA */
on uart
-i ionull -o ionull -c ionull
-r ionull -g ionull -p ionull
-w ionull -s ioerr -n ionull
-intr ionull
/* type of ram disk */
/* RAFA
ram:
on mem
-i raminit -o ramopen -c ramclose
-r ramread -g ioerr -p ioerr
-w ramwrite -s ioerr -n ioerr
-intr ionull
FIN DE RAFA */
/* type of namespace device */
nam:
on top
-i naminit -o namopen -c ioerr
-r ioerr -g ioerr -p ioerr
-w ioerr -s ioerr -n ioerr
-intr ioerr
/* RAFA
spi:
on standard_spi
-i spiinit -o ioerr -c ioerr
-r ioerr -g ioerr -p spiputc
-w ioerr -s ioerr -n ioerr
-intr ioerr
FIN DE RAFA */
%%
/* Actual device declarations that each give the name of a device that */
/* will be present in the system */
/* Define the console device to be a tty and specify CSR*/
CONSOLE is tty on uart csr 0x40013800 -irq 53
/* Define the console device to be a tty and specify CSR*/
/* RAFA GPIO0 is gpio on standard_gpio csr 0x40010800 -irq 99 */
/* Define the console device to be a tty and specify CSR*/
/* RAFA GPIO1 is gpio on standard_gpio csr 0x40010C00 -irq 99 */
/* Define the console device to be a tty and specify CSR*/
/* RAFA GPIO2 is gpio on standard_gpio csr 0x40011000 -irq 99 */
/* Define the console device to be a tty and specify CSR*/
/* RAFA GPIO3 is gpio on standard_gpio csr 0x40011400 -irq 99 */
/* Define a null device */
NULLDEV is null on nothing
/* Define a namespace device */
NAMESPACE is nam on top
/* Define a SPI device */
/* RAFA SPI1 is spi on standard_spi */
/* Define a ram disk device */
/* RAFA RAM0 is ram on mem */
%%
/* Configuration and Size Constants */
#define NPROC 4 /* number of user processes */
#define NSEM 4 /* number of semaphores */
#define IRQBASE 32 /* base ivec for IRQ0 */
#define IRQ_TIMER IRQ_HW5 /* timer IRQ is wired to hardware 5 */
#define IRQ_ATH_MISC IRQ_HW4 /* Misc. IRQ is wired to hardware 4 */
#define CLKFREQ 200000000 /* 200 MHz clock */
// #define LF_DISK_DEV RAM0

106
config/Configuration.orig

@ -0,0 +1,106 @@
/************************************************************************/
/* */
/* Configuration - Xinu device configuration specification file */
/* */
/* This file becomes input to the config program, which generates */
/* conf.h and conf.c */
/* */
/* Entries for a device specify the functions that handle each of the */
/* high-level I/O operations as follows: */
/* */
/* -i init -o open -c close */
/* -r read -w write -s seek */
/* -g getc -p putc -n control */
/* -intr int_hndlr -csr csr -irq irq */
/* */
/************************************************************************/
/* Type Declarations for both real- and pseudo- device types */
/* type of a null device */
null:
on nothing
-i ionull -o ionull -c ionull
-r ionull -g ionull -p ionull
-w ionull -s ioerr
/* type of a gpio device */
gpio:
on standard_gpio
-i gpioinit -o ionull -c ionull
-r gpioread -g ionull -p ionull
-w gpiowrite -s ioerr -n gpiocontrol
-intr gpiohandler
/* type of a tty device */
tty:
on uart
-i ttyinit -o ionull -c ionull
-r ttyread -g ttygetc -p ttyputc
-w ttywrite -s ioerr -n ttycontrol
-intr ttyhandler
/* type of ram disk */
ram:
on mem
-i raminit -o ramopen -c ramclose
-r ramread -g ioerr -p ioerr
-w ramwrite -s ioerr -n ioerr
-intr ionull
/* type of namespace device */
nam:
on top
-i naminit -o namopen -c ioerr
-r ioerr -g ioerr -p ioerr
-w ioerr -s ioerr -n ioerr
-intr ioerr
spi:
on standard_spi
-i spiinit -o ioerr -c ioerr
-r ioerr -g ioerr -p spiputc
-w ioerr -s ioerr -n ioerr
-intr ioerr
%%
/* Actual device declarations that each give the name of a device that */
/* will be present in the system */
/* Define the console device to be a tty and specify CSR*/
CONSOLE is tty on uart csr 0x40013800 -irq 53
/* Define the console device to be a tty and specify CSR*/
GPIO0 is gpio on standard_gpio csr 0x40010800 -irq 99
/* Define the console device to be a tty and specify CSR*/
GPIO1 is gpio on standard_gpio csr 0x40010C00 -irq 99
/* Define the console device to be a tty and specify CSR*/
GPIO2 is gpio on standard_gpio csr 0x40011000 -irq 99
/* Define the console device to be a tty and specify CSR*/
GPIO3 is gpio on standard_gpio csr 0x40011400 -irq 99
/* Define a null device */
NULLDEV is null on nothing
/* Define a namespace device */
NAMESPACE is nam on top
/* Define a SPI device */
SPI1 is spi on standard_spi
/* Define a ram disk device */
RAM0 is ram on mem
%%
/* Configuration and Size Constants */
#define NPROC 10 /* number of user processes */
#define NSEM 10 /* number of semaphores */
#define IRQBASE 32 /* base ivec for IRQ0 */
#define IRQ_TIMER IRQ_HW5 /* timer IRQ is wired to hardware 5 */
#define IRQ_ATH_MISC IRQ_HW4 /* Misc. IRQ is wired to hardware 4 */
#define CLKFREQ 200000000 /* 200 MHz clock */
#define LF_DISK_DEV RAM0

111
config/DESCRIPTION

@ -0,0 +1,111 @@
This is the Xinu config program that allows one to specify a set of
device drivers.
Input: the program reads specifications from an input file, usually
Configuration
Output: the program produces two ouput files, usually
conf.h - configuration constants and declarations
for device drivers and the device
switch table
conf.c - initialization code for data strcutures
declared in conf.h
The input file consists of three sections, with %% used as a sparator
between sections:
----------------------------------------------------------------------------
/* Comments can appear anywhere in the input file; use */
/* the C style of slash-star ... star-slash. */
/* The config program ignores whitespace and comments. */
device type declarations
%%
device declarations
%%
Other constants added to conf.h (typically, #defines)
----------------------------------------------------------------------------
**************************** Type Declarations *****************************
The type declaration section consists of a series of entries of the form:
type_name: on hardware_name [options]
where
type_name a name for the type
: a required punctuation, usually appended onto the
type name
on a keyword
hardware_name any string used to allow a type name to have
two implementations
options multiple options can be specified, and each
consists of a flag and the name of a
driver function or hardware parameter
(the minus sign in front of a flag
can be omitted):
-i initialization_function
-o open_function
-r read_function
-w write_function
-s seek_function
-c close_function
-g getc_function
-p putc_function
-n control_function
-intr interrupt_handler
-csr CSR address
-irq Interrupt request number
Example:
eth: on quark_eth
-i ethinit -o ioerr -c ioerr
-r ethread -g ioerr -p ioerr
-w ethwrite -s ioerr -n ethcontrol
-intr ethdispatch
*************************** Device Declarations ****************************
The device declaration section consists of one entry per device in the form:
device_name is type_name on hardware_name [options]
where
device_name a name for the device (by convention, Xinu
uses upper-case device names)
is a keyword
type_name the name of a type defined above
on a keyword
hardware_name must match one of the hardware names used with
when the type was defined
options the same as the options above -- any values used
on a device declaration override the
values defined for the type. Typically,
a type does not have specific hardware
parameters, so they must be filled in.
Example:
ETHER is eth on quark_eth csr 0001770 -irq 0053

41
config/Makefile

@ -0,0 +1,41 @@
#
# Make the Xinu configuration program
#
COMPILER_ROOT = /usr/bin/
CC = ${COMPILER_ROOT}gcc
LEX = ${COMPILER_ROOT}flex
YACC = ${COMPILER_ROOT}bison -y # Flag enables yacc-compatible filenames
CFLAGS =
LFLAGS = -lfl
#
# Name of the configuration program
#
CONFIG = config
all: conf.h conf.c
${CONFIG}: lex.yy.c y.tab.c
$(CC) ${CFLAGS} -o $@ y.tab.c ${LFLAGS}
lex.yy.c: config.l
$(LEX) config.l
y.tab.c: config.y
$(YACC) config.y
clean:
rm -f config lex.yy.c y.tab.c
conf.h: config Configuration
./config Configuration conf.c conf.h
conf.c: config Configuration
./config Configuration conf.c conf.h
install: conf.h conf.c
cp -p conf.h ../include
cp -p conf.c ../system

44
config/conf.c

@ -0,0 +1,44 @@
/* conf.c (GENERATED FILE; DO NOT EDIT) */
#include <xinu.h>
extern devcall ioerr(void);
extern devcall ionull(void);
/* Device independent I/O switch */
typedef unsigned int size_t;
#include <avr/pgmspace.h>
const struct dentry devtab[] PROGMEM =
{
/**
* Format of entries is:
* dev-number, minor-number, dev-name,
* init, open, close,
* read, write, seek,
* getc, putc, control,
* dev-csr-address, intr-handler, irq
*/
/* CONSOLE is tty */
{ 0, 0, "CONSOLE",
(void *)ionull, (void *)ionull, (void *)ionull,
(void *)ionull, (void *)ionull, (void *)ioerr,
(void *)ionull, (void *)ionull, (void *)ionull,
(void *)0x40013800, (void *)ionull, 53 },
/* NULLDEV is null */
{ 1, 0, "NULLDEV",
(void *)ionull, (void *)ionull, (void *)ionull,
(void *)ionull, (void *)ionull, (void *)ioerr,
(void *)ionull, (void *)ionull, (void *)ioerr,
(void *)0x0, (void *)ioerr, 0 },
/* NAMESPACE is nam */
{ 2, 0, "NAMESPACE",
(void *)naminit, (void *)namopen, (void *)ioerr,
(void *)ioerr, (void *)ioerr, (void *)ioerr,
(void *)ioerr, (void *)ioerr, (void *)ioerr,
(void *)0x0, (void *)ioerr, 0 }
};

50
config/conf.h

@ -0,0 +1,50 @@
/* conf.h (GENERATED FILE; DO NOT EDIT) */
/* Device switch table declarations */
/* Device table entry */
struct dentry {
int32 dvnum;
int32 dvminor;
char dvname[16];
devcall (*dvinit) (struct dentry *);
devcall (*dvopen) (struct dentry *, char *, char *);
devcall (*dvclose)(struct dentry *);
devcall (*dvread) (struct dentry *, void *, uint32);
devcall (*dvwrite)(struct dentry *, void *, uint32);
devcall (*dvseek) (struct dentry *, int32);
devcall (*dvgetc) (struct dentry *);
devcall (*dvputc) (struct dentry *, char);
devcall (*dvcntl) (struct dentry *, int32, int32, int32);
void *dvcsr;
void (*dvintr)(void);
byte dvirq;
};
extern const struct dentry devtab[]; /* one entry per device */
/* Device name definitions */
#define CONSOLE 0 /* type tty */
#define NULLDEV 1 /* type null */
#define NAMESPACE 2 /* type nam */
/* Control block sizes */
#define Nnull 1
#define Ntty 1
#define Nnam 1
#define NDEVS 3
/* Configuration and Size Constants */
#define NPROC 4 /* number of user processes */
#define NSEM 4 /* number of semaphores */
#define IRQBASE 32 /* base ivec for IRQ0 */
#define IRQ_TIMER IRQ_HW5 /* timer IRQ is wired to hardware 5 */
#define IRQ_ATH_MISC IRQ_HW4 /* Misc. IRQ is wired to hardware 4 */
#define CLKFREQ 200000000 /* 200 MHz clock */
// #define LF_DISK_DEV RAM0

40
config/config.l

@ -0,0 +1,40 @@
%{
extern int linectr;
extern int brkcount;
int skipping;
%}
OCT 0[0-7]*
DEC [1-9][0-9]*
HEX 0x[0-9a-fA-F]+
ID [a-z_A-Z][a-z_A-Z0-9]*
%%
"/*" { skipping = 1; }
"*/" { skipping = 0; }
"%%" { if (! skipping)
if (++brkcount >= 2)
{ return 0; /* EOF */ }
else
{ return DEFBRK; } }
":" { if (! skipping) return COLON; }
{OCT} { if (! skipping) return INTEGER; }
{DEC} { if (! skipping) return INTEGER; }
{HEX} { if (! skipping) return INTEGER; }
is { if (! skipping) return IS; }
on { if (! skipping) return ON; }
"=" ;
-?intr { if (! skipping) return INTR; }
-?csr { if (! skipping) return CSR; }
-?irq { if (! skipping) return IRQ; }
-?i { if (! skipping) return INIT; }
-?o { if (! skipping) return OPEN; }
-?c { if (! skipping) return CLOSE; }
-?r { if (! skipping) return READ; }
-?g { if (! skipping) return GETC; }
-?p { if (! skipping) return PUTC; }
-?w { if (! skipping) return WRITE; }
-?s { if (! skipping) return SEEK; }
-?n { if (! skipping) return CONTROL; }
[ \t]+ ;
"\n" { linectr++; }
{ID} { if (! skipping) return IDENT; }
. { if (! skipping) return yytext[0]; }

754
config/config.y

@ -0,0 +1,754 @@
/* config.y - yacc input file for the Xinu config program */
/************************************************************************/
/* */
/* This file contains the yacc grammar and semantic functions */
/* that read a Xinu Configuration file and generate output files */
/* conf.h and conf.c that are then compiled along with the rest of */
/* Xinu. */
/* */
/************************************************************************/
%token DEFBRK IFBRK COLON OCTAL INTEGER IDENT CSR IRQ INTR INIT OPEN
CLOSE READ WRITE SEEK CONTROL IS ON GETC PUTC
%{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
extern char *yytext;
/*
Work-around for the type conflict that results from unmatched versions
of flex and bison (lex and yacc). The idea is to force the new flex
style so the output file (lex.yy.c) treats yyleng as an int (as was
done by oldest lex versions) instead of a size_t. We override the
new flex typedef of yy_size_t.
*/
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef int yy_size_t;
#endif
/* End work-around */
extern int yyleng;
/********************************************************************************/
/* */
/* Start of Definitions */
/* */
/********************************************************************************/
#define NIL (struct dev_ent *)0x00
#define CONFC "conf.c" /* Name of .c output */
#define CONFH "conf.h" /* Name of .h output */
#define CONFHREF "<conf.h>" /* How conf.h referenced */
#define INFILE "Configuration" /* Name of input file */
// RAFA #define MAXNAME 16 /* Max length of names */
#define MAXNAME 16 /* Max length of names */
// RAFA #define NDEVS 250 /* Max devices */
// RAFA #define NTYPES 250 /* Max device types */
#define NDEVS 5 /* Max devices */
#define NTYPES 5 /* Max device types */
int linectr = 1;
FILE *confc;
FILE *confh;
int brkcount = 0; /* Count of %% separators till now in */
/* the input file */
char *doing = "device type declarations";
struct dev_ent { /* Entry for a device or device type */
char name[MAXNAME]; /* device name (unused in a type) */
char tname[MAXNAME]; /* Type name */
char ison[MAXNAME]; /* Name is "on" XXX */
int tindex; /* Index in dtypes (unused in a type) */
int csr; /* Control Status Register addr */
int irq; /* interrupt request */
char intr[MAXNAME]; /* interrupt function name */
char init[MAXNAME]; /* init function name */
char open[MAXNAME]; /* open function name */
char close[MAXNAME]; /* close function name */
char read[MAXNAME]; /* read function name */
char write[MAXNAME]; /* write function name */
char control[MAXNAME]; /* control function name */
char seek[MAXNAME]; /* seek function name */
char getc[MAXNAME]; /* getc function name */
char putc[MAXNAME]; /* putc function name */
int minor; /* In a device, the minor device */
/* assigned to the device 0,1,... */
/* in a type, the next minor number */
/* to assign */
};
struct dev_ent dtypes[NTYPES];/* Table of all device types */
int ntypes = 0; /* Number of device types found */
struct dev_ent devs[NDEVS]; /* Table of all devices */
int ndevs = 0; /* Number of devices found */
char *devstab[] = {
"/* Device table entry */",
"struct\tdentry\t{",
"\tint32 dvnum;",
"\tint32 dvminor;",
// RAFA "\tchar *dvname;",
"\tchar dvname[16];",
"\tdevcall (*dvinit) (struct dentry *);",
"\tdevcall (*dvopen) (struct dentry *, char *, char *);",
"\tdevcall (*dvclose)(struct dentry *);",
"\tdevcall (*dvread) (struct dentry *, void *, uint32);",
"\tdevcall (*dvwrite)(struct dentry *, void *, uint32);",
"\tdevcall (*dvseek) (struct dentry *, int32);",
"\tdevcall (*dvgetc) (struct dentry *);",
"\tdevcall (*dvputc) (struct dentry *, char);",
"\tdevcall (*dvcntl) (struct dentry *, int32, int32, int32);",
"\tvoid *dvcsr;",
"\tvoid (*dvintr)(void);",
"\tbyte dvirq;",
"};\n",
"extern const struct dentry devtab[]; /* one entry per device */",
NULL
};
char saveattrid[MAXNAME]; /* Holds the IDENT from an attribute */
/********************************************************************************/
/* */
/* Function prototypes */
/* */
/********************************************************************************/
void addattr(int, int);
int addton(char *);
int config_atoi(char *, int);
void devisid(char *);
void devonid(char *);
void getattrid(char *);
void newdev(char *);
int newtype(char *);
void yyerror(char *);
%}
%%
/************************************************************************/
/* */
/* Grammar rules for the entire Configuration */
/* */
/************************************************************************/
configuration: devtypes DEFBRK devices
;
/************************************************************************/
/* */
/* Grammar rules for device types */
/* */
/************************************************************************/
devtypes: /* nothing */ { doing = "device definitions"; }
| devtypes devtype
;
devtype: tname COLON dev_tlist
;
tname: IDENT { $$ = newtype(yytext); }
;
dev_tlist: theader attr_list
| dev_tlist theader attr_list
;
theader: ON tonid { $$ = $2; }
;
tonid: IDENT { $$ = addton(yytext); }
;
attr_list: /* nothing */
| attr_list attr
;
attr: CSR number { addattr(CSR, $2); }
| IRQ number { addattr(IRQ, $2); }
| INTR id { addattr(INTR, 0); }
| OPEN id { addattr(OPEN, 0); }
| CLOSE id { addattr(CLOSE, 0); }
| INIT id { addattr(INIT, 0); }
| GETC id { addattr(GETC, 0); }
| PUTC id { addattr(PUTC, 0); }
| READ id { addattr(READ, 0); }
| WRITE id { addattr(WRITE, 0); }
| SEEK id { addattr(SEEK, 0); }
| CONTROL id { addattr(CONTROL, 0); }
;
id: IDENT { $$ = 0; getattrid(yytext); }
;
number: INTEGER { $$ = config_atoi(yytext, yyleng); }
;
/************************************************************************/
/* */
/* Grammar rules for device definitions */
/* */
/************************************************************************/
devices: /* nothing */ { doing = "interface types"; }
| devices device
;
device: dheader attr_list
;
dheader: dname devis devon
;
dname: IDENT { newdev(yytext); }
;
devis: IS devisid
;
devisid: IDENT { devisid(yytext); }
;
devon: ON devonid
;
devonid: IDENT { devonid(yytext); }
;
%%
#include "lex.yy.c"
/************************************************************************/
/* */
/* main - main program: parse arguments, invoke the parser, and */
/* write the conf.h and conf.c files */
/* */
/************************************************************************/
int main(int argc, char **argv) {
int n, i, j, l, fcount;
struct dev_ent *s;
int verbose = 0;
char *p;
int c;
if ( argc > 1 && (strncmp("-v", argv[1], 2) == 0) ) {
argc--;
argv++;
verbose++;
}
if ( argc > 4 ) {
fprintf(stderr, "use: config [-v] [input_file] [conf.c] [conf.h]\n");
exit(1);
}
if (verbose) { printf("Opening input file...\n"); }
if (argc >= 2) {
if (freopen(argv[1], "r", stdin) == NULL) {
fprintf(stderr, "Can't open %s\n", argv[1]);
exit(1);
}
}
else { /* try to open Configuration file */
if (freopen(INFILE, "r", stdin) == NULL) {
fprintf(stderr, "Can't open %s\n", INFILE);
exit(1);
}
}
/****************************************************************/
/* */
/* Parse the Configuration file */
/* */
/****************************************************************/
if (verbose) { printf("Parsing configuration specs...\n"); }
if ( (n = yyparse()) != 0 ) { exit(n); }
/* Open conf.h and conf.c for writing */
if (verbose) { printf("Opening output files...\n"); }
if (argc >= 3) {
if ( (confc = fopen(argv[2],"w") ) == NULL) {
fprintf(stderr, "Can't write on %s\n", argv[2]);
exit(1);
}
}
else { /* try to open conf.c file */
if ( (confc = fopen(CONFC,"w") ) == NULL) {
fprintf(stderr, "Can't write on %s\n", CONFC);
exit(1);
}
}
if (argc >= 4) {
if ( (confh = fopen(argv[3],"w") ) == NULL) {
fprintf(stderr, "Can't write on %s\n", argv[3]);
exit(1);
}
}
else { /* try to open conf.h file */
if ( (confh = fopen(CONFH,"w") ) == NULL) {
fprintf(stderr, "Can't write on %s\n", CONFH);
exit(1);
}
}
/****************************************************************/
/* */
/* produce conf.h */
/* */
/****************************************************************/
fprintf(confh, "/* conf.h (GENERATED FILE; DO NOT EDIT) */\n\n");
if (verbose) { printf("Writing output...\n"); }
fprintf(confh, "/* Device switch table declarations */\n\n");
for (i = 0; (p = devstab[i]) != NULL; i++) {
fprintf(confh, "%s\n", p);
}
fprintf(confh, "\n");
/* write device declarations and definitions */
fprintf(confh, "/* Device name definitions */\n\n");
for (i = 0; i<ndevs; i++) {
s = &devs[i];
fprintf(confh, "#define %-20s%2d\t/* type %-8s */\n",
s->name, i, s->tname);
}
fprintf(confh, "\n");
/* write count of device types */
fprintf(confh, "/* Control block sizes */\n\n");
for (i = 0; i < ntypes; i++) {
s = &dtypes[i];
if (s->minor > 0) {
fprintf(confh, "#define\tN%s\t%d\n",
s->tname, s->minor);
}
}
fprintf(confh, "\n");
if (ndevs > 0) { fprintf(confh, "#define NDEVS %d\n", ndevs); }
/* Copy definitions to output */
if (brkcount >= 4 && verbose) {
printf("Copying definitions to %s...\n", CONFH);
}
if (brkcount >= 2) {
while ( (c = input()) > 0) { /* lex input function */
putc(c, confh);
}
}
fclose(confh);
/****************************************************************/
/* */
/* produce conf.c */
/* */
/****************************************************************/
fprintf(confc, "/* conf.c (GENERATED FILE; DO NOT EDIT) */\n\n");
fprintf(confc, "#include <xinu.h>\n\n");
fprintf(confc, "\n");
fprintf(confc, "extern\tdevcall\tioerr(void);\n");
fprintf(confc, "extern\tdevcall\tionull(void);\n\n");
/* produce devtab (giant I/O switch table) */
fprintf(confc, "/* Device independent I/O switch */\n\n");
if (ndevs > 0)
{
// RAFA fprintf(confc, "const struct dentry devtab[NDEVS] =\n{\n");
fprintf(confc, "typedef unsigned int size_t;\n");
fprintf(confc, "#include <avr/pgmspace.h>\n");
fprintf(confc, "const struct dentry devtab[] PROGMEM =\n{\n");
// RAFA fprintf(confc, "const struct dentry devtab[] PROGMEM =\n{\n");
fprintf(confc, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n\n",
"/**",
" * Format of entries is:",
" * dev-number, minor-number, dev-name,",
" * init, open, close,",
" * read, write, seek,",
" * getc, putc, control,",
" * dev-csr-address, intr-handler, irq",
" */");
}
for (i=0; i<ndevs; i++) {
s = &devs[i];
fprintf(confc, "/* %s is %s */\n", s->name, s->tname);
fprintf(confc, "\t{ %d, %d, \"%s\",\n", i, s->minor, s->name);
fprintf(confc, "\t (void *)%s, (void *)%s, (void *)%s,\n",
s->init, s->open, s->close);
fprintf(confc, "\t (void *)%s, (void *)%s, (void *)%s,\n",
s->read, s->write, s->seek);
fprintf(confc, "\t (void *)%s, (void *)%s, (void *)%s,\n",
s->getc, s->putc, s->control);
fprintf(confc, "\t (void *)0x%x, (void *)%s, %d }",
s->csr, s->intr, s->irq);
if (i< ndevs-1) {
fprintf(confc, ",\n\n");
} else {
fprintf(confc, "\n};");
}
}
/* we must guarantee conf.c written later than conf.h for make */
fprintf(confc, "\n");
fclose(confc);
/* finish up and write report for user if requested */
if (verbose) {
printf("Configuration complete. Number of devs=%d:\n", ndevs);
for (i=0; i<ndevs; i++) {
s = &devs[i];
printf("Device %s (on %s)\n", s->name, s->ison);
printf(" csr=0x%04x, irq=0x%04x, minor=%d\n",
s->csr, s->irq, s->minor);
}
}
}
/************************************************************************/
/* */
/* addattr - add a new attribute spec to current type/device description*/
/* tok: token type (attribute type) */
/* val: symbol number of value */
/* */
/************************************************************************/
void addattr(int tok, int val) {
struct dev_ent *s;
char *c;
if (brkcount == 0) {
/* Doing types */
s = &dtypes[ntypes-1];
} else {
/* Doing devices */
s = &devs[ndevs-1];
}
switch (tok) {
case CSR: s->csr = val; break;
case IRQ: s->irq = val; break;
case INTR: strcpy(s->intr, saveattrid); break;
case READ: strcpy(s->read, saveattrid); break;
case WRITE: strcpy(s->write,saveattrid); break;
case GETC: strcpy(s->getc, saveattrid); break;
case PUTC: strcpy(s->putc, saveattrid); break;
case OPEN: strcpy(s->open, saveattrid); break;
case CLOSE: strcpy(s->close,saveattrid); break;
case INIT: strcpy(s->init, saveattrid); break;
case SEEK: strcpy(s->seek, saveattrid); break;
case CONTROL: strcpy(s->control,saveattrid); break;
default: fprintf(stderr, "Internal error 1\n");
}
}
/************************************************************************/
/* */
/* addton -- add an "on XXX" to the current type */
/* */
/************************************************************************/
int addton(char *tonid) {
int currtype; /* The current type */
if (strlen(tonid) >= MAXNAME) {
fprintf(stderr,"string %s is too long on line %d\n",
tonid, linectr);
exit(1);
}
currtype = ntypes - 1;
strcpy(dtypes[currtype].ison, tonid);
return currtype;
}
/************************************************************************/
/* */
/* config_atoi - convert an ascii string of text to an integer, */
/* honoring octal, decimal, and hex */
/* */
/************************************************************************/
int config_atoi(char *p, int len) {
int base, rv;
if (*p == '0')
{
++p;
--len;
if (*p == 'x' || *p == 'X')
{
++p; --len; /* skip 'x' */
base = 16;
}
else
{
base = 8;
}
}
else
{
base = 10;
}
rv = 0;
for (; len > 0; ++p, --len)
{
rv *= base;
if (isdigit(*p)) { rv += *p - '0'; }
else if (isupper(*p)) { rv += *p - 'A' + 10; }
else { rv += *p - 'a' + 10; }
}
return rv;
}
/************************************************************************/
/* */
/* devisid -- add an "is XXX" to the current device */
/* */
/************************************************************************/
void devisid(char *tname) {
int currdev; /* The current device */
int i;
if (strlen(tname) >= MAXNAME) {
fprintf(stderr,"string %s is too long on line %d\n",
tname, linectr);
exit(1);
}
/* Verify the type exists */
for (i=0; i<ntypes; i++) {
if (strcmp(tname, dtypes[i].tname) == 0) {
break;
}
}
if (i >= ntypes) {
fprintf(stderr, "Illegal type name %s on line %d\n",
tname, linectr);
exit(1);
}
currdev = ndevs - 1;
strcpy(devs[currdev].tname, tname);
return;
}
/************************************************************************/
/* */
/* devonid -- add an "on XXX" to the current device, lookup the type, */
/* and copy attributes into the device from the type */
/* */
/************************************************************************/
void devonid(char *onname) {
int currdev; /* The current device */
int i;
struct dev_ent *dptr; /* Pointer to current device */
struct dev_ent *tptr; /* Pointer to a type */
char tmp[MAXNAME]; /* Holds the device name during */
/* copy */
if (strlen(onname) >= MAXNAME) {
fprintf(stderr,"string %s is too long on line %d\n",
onname, linectr);
exit(1);
}
if (ndevs <=0) {
fprintf(stderr,"Internal error 3\n");
exit(1);
}
currdev = ndevs - 1;
dptr = &devs[currdev];
strcpy(dptr->ison, onname);
/* Lookup the device type */
for (i=0; i<ntypes; i++) {
tptr = &dtypes[i];
if ( (strcmp(dptr->tname,tptr->tname) == 0 ) &&
(strcmp(dptr->ison, tptr->ison) == 0 ) ){
/* The specified type matches the ith entry, so */
/* set all attributes equal to the ones in the */
/* type definition. */
strcpy(tmp, dptr->name);
bcopy (tptr, dptr, sizeof(struct dev_ent));
/* Increment the minor device number for the */
/* next time the type is used */
tptr->minor++;
strcpy(dptr->name, tmp);
return;
}
}
fprintf(stderr, "Ileagal device specification on line %d\n", linectr);
exit(1);
}
/************************************************************************/
/* */
/* getattrid -- pick up and save the attribute string from an id */
/* */
/************************************************************************/
void getattrid(char *str) {
if (strlen(str) >= MAXNAME) {
fprintf(stderr,"atribute string %s is too long on line %d\n",
str, linectr);
exit(1);
}
strcpy(saveattrid, str);
return;
}
/************************************************************************/
/* */
/* newdev -- allocate an entry in devs, initialize, and fill in the name*/
/* */
/************************************************************************/
void newdev(char *name) {
struct dev_ent *dptr; /* Ptr. to an entry in devs */
int i;
if (ndevs >= NDEVS) {
fprintf(stderr,"Too many devices on line %d", linectr);
exit(1);
}
if (strlen(name) >= MAXNAME) {
fprintf(stderr,"Device name %s is too long on line %d\n",
name, linectr);
exit(1);
}
/* Verify that the device name is unique */
for (i=0; i<ndevs; i++) {
if (strcmp(name, devs[i].name) == 0) {
fprintf(stderr, "Duplicate device name %s on line %d\n",
name, linectr);
exit(1);
}
}
dptr = &devs[ndevs];
/* Initialize fields in the entry */
bzero((void *)dptr, sizeof(struct dev_ent));
strcpy(dptr->name, name);
ndevs++;
return;
}
/************************************************************************/
/* */
/* newtype -- allocate an entry in the type array and fill in the name */
/* */
/************************************************************************/
int newtype(char *name) {
struct dev_ent *dptr; /* Ptr. to an entry in dtypes */
int i; /* Index into the type table */
if (ntypes >= NTYPES) {
fprintf(stderr,"Too many types on line %d", linectr);
exit(1);
}
if (strlen(name) >= MAXNAME) {
fprintf(stderr,"Type name %s is too long on line %d\n",
name, linectr);
exit(1);
}
/* Verify that the type name is unique */
for (i=0; i<ntypes; i++) {
if (strcmp(name, dtypes[i].tname) == 0) {
fprintf(stderr, "Duplicate type name %s on line %d\n",
name, linectr);
exit(1);
}
}
dptr = &dtypes[ntypes];
/* Initialize fields in the entry */
bzero((void *)dptr, sizeof(struct dev_ent));
strcpy(dptr->tname, name);
strncpy(dptr->intr, "ioerr", 5);
strncpy(dptr->init, "ioerr", 5);
strncpy(dptr->open, "ioerr", 5);
strncpy(dptr->close, "ioerr", 5);
strncpy(dptr->read, "ioerr", 5);
strncpy(dptr->write, "ioerr", 5);
strncpy(dptr->control, "ioerr", 5);
strncpy(dptr->seek, "ioerr", 5);
strncpy(dptr->getc, "ioerr", 5);
strncpy(dptr->putc, "ioerr", 5);
return ntypes++;
}
/************************************************************************/
/* */
/* yyerror - print an error message with the line number */
/* */
/************************************************************************/
void yyerror(char *s) {
fprintf(stderr, "Syntax error in %s on line %d\n", doing, linectr);
}

35
device/eth/ethcontrol.c

@ -0,0 +1,35 @@
/* ethcontrol.c - ethcontrol */
#include <xinu.h>
/*------------------------------------------------------------------------
* ethcontrol - implement control function for a quark ethernet device
*------------------------------------------------------------------------
*/
devcall ethcontrol (
struct dentry *devptr, /* entry in device switch table */
int32 func, /* control function */
int32 arg1, /* argument 1, if needed */
int32 arg2 /* argument 2, if needed */
)
{
struct ethcblk *ethptr; /* Ethertab entry pointer */
int32 retval = OK; /* Return value of cntl function*/
ethptr = &ethertab[devptr->dvminor];
switch (func) {
/* Get MAC address */
case ETH_CTRL_GET_MAC:
memcpy((byte *)arg1, ethptr->devAddress,
ETH_ADDR_LEN);
break;
default:
return SYSERR;
}
return retval;
}

123
device/eth/ethhandler.c

@ -0,0 +1,123 @@
/* ethhandler.c - ethhandler */
#include <xinu.h>
/*------------------------------------------------------------------------
* ethhandler - TI AM335X Ethernet Interrupt Handler
*------------------------------------------------------------------------
*/
interrupt ethhandler (
uint32 xnum /* IRQ number */
)
{
struct eth_a_csreg *csrptr; /* Ethernet CSR pointer */
struct eth_a_tx_desc *tdescptr; /* Tx desc pointer */
struct eth_a_rx_desc *rdescptr; /* Rx desc pointer */
struct ethcblk *ethptr = &ethertab[0]; /* Ethernet ctl blk ptr */
csrptr = (struct eth_a_csreg *)ethptr->csr;
if(xnum == ETH_AM335X_TXINT) { /* Transmit interrupt */
/* Get pointer to first desc in queue */
tdescptr = (struct eth_a_tx_desc *)ethptr->txRing +
ethptr->txHead;
/* Defer scheduling until all descs are processed */
resched_cntl(DEFER_START);
while(semcount(ethptr->osem) < (int32)ethptr->txRingSize) {
/* If desc owned by DMA, check if we need to */
/* Restart the transmission */
if(tdescptr->stat & ETH_AM335X_TDS_OWN) {
if(csrptr->stateram->tx_hdp[0] == 0) {
csrptr->stateram->tx_hdp[0] =
(uint32)tdescptr;
}
break;
}
/* Acknowledge the interrupt */
csrptr->stateram->tx_cp[0] = (uint32)tdescptr;
/* Increment the head index of the queue */
/* And go to the next descriptor in queue */
ethptr->txHead++;
tdescptr++;
if(ethptr->txHead >= ethptr->txRingSize) {
ethptr->txHead = 0;
tdescptr = (struct eth_a_tx_desc *)
ethptr->txRing;
}
/* Signal the output semaphore */
signal(ethptr->osem);
}
/* Acknowledge the transmit interrupt */
csrptr->cpdma->eoi_vector = 0x2;
/* Resume rescheduling */
resched_cntl(DEFER_STOP);
}
else if(xnum == ETH_AM335X_RXINT) { /* Receive interrupt */
/* Get the pointer to last desc in the queue */
rdescptr = (struct eth_a_rx_desc *)ethptr->rxRing +
ethptr->rxTail;
/* Defer scheduling until all descriptors are processed */
resched_cntl(DEFER_START);
while(semcount(ethptr->isem) < (int32)ethptr->rxRingSize) {
/* Check if we need to restart the DMA */
if(rdescptr->stat & ETH_AM335X_RDS_OWN) {
if(csrptr->stateram->rx_hdp[0] == 0) {
csrptr->stateram->rx_hdp[0] =
(uint32)rdescptr;
}
break;
}
/* Acknowledge the interrupt */
csrptr->stateram->rx_cp[0] = (uint32)rdescptr;
/* Increment the tail index of the queue */
/* And go to the next descriptor in the queue */
ethptr->rxTail++;
rdescptr++;
if(ethptr->rxTail >= ethptr->rxRingSize) {
ethptr->rxTail = 0;
rdescptr = (struct eth_a_rx_desc *)
ethptr->rxRing;
}
/* Signal the input semaphore */
signal(ethptr->isem);
}
/* Acknowledge the receive interrupt */
csrptr->cpdma->eoi_vector = 0x1;
/* Resume rescheduling */
resched_cntl(DEFER_STOP);
}
}

403
device/eth/ethinit.c

@ -0,0 +1,403 @@
/* ethinit.c - ethinit, eth_phy_read, eth_phy_write */
#include <xinu.h>
struct eth_a_csreg eth_a_regs;
struct ethcblk ethertab[1];
/*-----------------------------------------------------------------------
* eth_phy_read - read a PHY register
*-----------------------------------------------------------------------
*/
int32 eth_phy_read (
volatile struct eth_a_mdio *mdio,/* MDIO CSR pointer */
byte regadr, /* PHY Register number */
byte phyadr, /* PHY address */
uint32 *value /* Pointer to value */
)
{
/* Ethernet PHY has only 32 registers */
if(regadr > 31) {
return SYSERR;
}
/* Only 32 possible PHY addresses */
if(phyadr > 31) {
return SYSERR;
}
/* Wait for the previous access to complete */
while( (mdio->useraccess0 & ETH_AM335X_MDIOUA_GO) != 0 );
/* Start the access */
mdio->useraccess0 = (ETH_AM335X_MDIOUA_GO) |
(regadr << 21) |
(phyadr << 16);
/* Wait until the access is complete */
while( (mdio->useraccess0 & ETH_AM335X_MDIOUA_GO) != 0 );
/* Check if the access was successful */
if( (mdio->useraccess0 & ETH_AM335X_MDIOUA_ACK) == 0 ) {
return SYSERR;
}
/* Copy the value read */
(*value) = mdio->useraccess0 & ETH_AM335X_MDIOUA_DM;
return OK;
}
/*-----------------------------------------------------------------------
* eth_phy_write - write a PHY register
*-----------------------------------------------------------------------
*/
int32 eth_phy_write (
volatile struct eth_a_mdio *mdio, /* MDIO CSR pointer */
byte regadr, /* PHY register number */
byte phyadr, /* PHY address */
uint32 value /* Value to be written */
)
{
/* There are only 32 PHY registers */
if(regadr > 31) {
return SYSERR;
}
/* There are only 32 possible PHY addresses */
if(phyadr > 31) {
return SYSERR;
}
/* Wait for the previous access to complete */
while( (mdio->useraccess0 & ETH_AM335X_MDIOUA_GO) != 0);
/* Start the access */
mdio->useraccess0 = ETH_AM335X_MDIOUA_GO |
ETH_AM335X_MDIOUA_WR |
(regadr << 21) |
(phyadr << 16) |
(value & 0xffff);
/* Wait for the access to complete */
while( (mdio->useraccess0 & ETH_AM335X_MDIOUA_GO) != 0);
return OK;
}
/*-----------------------------------------------------------------------
* eth_phy_reset - Reset an Ethernet PHY
*-----------------------------------------------------------------------
*/
int32 eth_phy_reset (
volatile struct eth_a_mdio *mdio, /* MDIO CSR pointer */
byte phyadr /* PHY Address */
)
{
uint32 phyreg; /* Variable to hold ETH PHY register value */
int32 retries;/* Number of retries */
int32 retval; /* Return value of functions called here */
/* Read the PHY Control Register */
retval = eth_phy_read(mdio, ETH_PHY_CTLREG, phyadr, &phyreg);
if(retval == SYSERR) {
return SYSERR;
}
/* Set the Reset bit and write the register */
phyreg |= ETH_PHY_CTLREG_RESET;
eth_phy_write(mdio, ETH_PHY_CTLREG, phyadr, phyreg);
/* Check if Reset operation is complete */
for(retries = 0; retries < 10; retries++) {
if(eth_phy_read(mdio, ETH_PHY_CTLREG, phyadr, &phyreg) == SYSERR) {
return SYSERR;
}
if((phyreg & ETH_PHY_CTLREG_RESET) == 0) {
break;
}
else {
retries++;
DELAY(ETH_AM335X_INIT_DELAY);
continue;
}
}
if(retries >= 3) {
return SYSERR;
}
/* Check if the Link is established */
for(retries = 0; retries < 10; retries++) {
if(eth_phy_read(mdio, ETH_PHY_STATREG, phyadr, &phyreg) == SYSERR) {
return SYSERR;
}
if(phyreg & ETH_PHY_STATREG_LINK) {
break;
}
else {
retries++;
DELAY(ETH_AM335X_INIT_DELAY);
continue;
}
}
if(retries >= 3) {
return SYSERR;
}
return OK;
}
/*-----------------------------------------------------------------------
* ethinit - initialize the TI AM335X ethernet hardware
*-----------------------------------------------------------------------
*/
int32 ethinit (
struct dentry *devptr
)
{
struct ethcblk *ethptr; /* Ethernet control blk pointer */
struct eth_a_tx_desc *tdescptr;/* Tx descriptor pointer */
struct eth_a_rx_desc *rdescptr;/* Rx descriptor pointer */
struct netpacket *pktptr; /* Packet pointer */
struct eth_a_csreg *csrptr; /* Ethernet CSR pointer */
uint32 phyreg; /* Variable to store PHY reg val*/
int32 retval; /* Return value */
int32 i; /* Index variable */
/* Get the Ethernet control block address */
/* from the device table entry */
ethptr = &ethertab[devptr->dvminor];
/* Store the address of CSRs in the Ethernet control block */
csrptr = &eth_a_regs;
ethptr->csr = csrptr;
/* Initialize the addresses of all the submodules */
csrptr->ale = (struct eth_a_ale *)ETH_AM335X_ALE_ADDR;
csrptr->cpdma = (struct eth_a_cpdma *)ETH_AM335X_CPDMA_ADDR;
csrptr->sl = (struct eth_a_sl *)ETH_AM335X_SL1_ADDR;
csrptr->stateram = (struct eth_a_stateram *)
ETH_AM335X_STATERAM_ADDR;
csrptr->ss = (struct eth_a_ss *)ETH_AM335X_SS_ADDR;
csrptr->wr = (struct eth_a_wr *)ETH_AM335X_WR_ADDR;
csrptr->mdio = (struct eth_a_mdio *)ETH_AM335X_MDIO_ADDR;
/* Reset all the submodules */
csrptr->cpdma->reset = 1;
while(csrptr->cpdma->reset == 1);
csrptr->sl->reset = 1;
while(csrptr->sl->reset == 1);
csrptr->wr->reset = 1;
while(csrptr->wr->reset == 1) ;
csrptr->ss->reset = 1;
while(csrptr->ss->reset == 1) ;
/* Enable MDIO */
csrptr->mdio->ctrl |= ETH_AM335X_MDIOCTL_EN;
/* Reset the PHY */
retval = eth_phy_reset(csrptr->mdio, 0);
if(retval == SYSERR) {
kprintf("Cannot reset Ethernet PHY\n");
return SYSERR;
}
retval = eth_phy_read(csrptr->mdio, ETH_PHY_CTLREG, 0, &phyreg);
if(retval == SYSERR) {
return SYSERR;
}
if( (phyreg & ETH_PHY_CTLREG_SM) == ETH_PHY_10M ) {
kprintf("Ethernet Link is Up. Speed is 10Mbps\n");
}
else if( (phyreg & ETH_PHY_CTLREG_SM) == ETH_PHY_100M ) {
kprintf("Ethernet Link is Up. Speed is 100Mbps\n");
}
else if( (phyreg & ETH_PHY_CTLREG_SM) == ETH_PHY_1000M ) {
kprintf("Ethernet Link is Up. Speed is 1000Mbps\n");
}
else {
return SYSERR;
}
if(phyreg & ETH_PHY_CTLREG_FD) {
kprintf("Link is Full Duplex\n");
csrptr->sl->macctrl |= ETH_AM335X_SLCTL_FD;
}
else {
kprintf("Link is Half Duplex\n");
}
/* Read the device MAC address */
for(i = 0; i < 2; i++) {
ethptr->devAddress[4+i] = *((byte *)(0x44e10630+i));
}
for(i = 0; i < 4; i++) {
ethptr->devAddress[i] = *((byte *)(0x44e10634+i));
}
kprintf("MAC Address is: ");
for(i = 0; i < 5; i++) {
kprintf("%02X:", ethptr->devAddress[i]);
}
kprintf("%02X\n", ethptr->devAddress[5]);
/* Initialize the rx ring size field */
ethptr->rxRingSize = ETH_AM335X_RX_RING_SIZE;
/* Allocate memory for the rx ring */
ethptr->rxRing = (void*)getmem(sizeof(struct eth_a_rx_desc)*
ethptr->rxRingSize);
if((int32)ethptr->rxRing == SYSERR) {
return SYSERR;
}
/* Zero out the rx ring */
memset((char*)ethptr->rxRing, NULLCH,
sizeof(struct eth_a_rx_desc)*ethptr->rxRingSize);
/* Allocate memory for rx buffers */
ethptr->rxBufs = (void*)getmem(ETH_BUF_SIZE *
ethptr->rxRingSize);
if((int32)ethptr->rxBufs == SYSERR) {
return SYSERR;
}
/* Zero out the rx buffers */
memset((char *)ethptr->rxBufs, NULLCH, ETH_BUF_SIZE *
ethptr->rxRingSize);
/* Initialize the rx ring */
rdescptr = (struct eth_a_rx_desc *)ethptr->rxRing;
pktptr = (struct netpacket *)ethptr->rxBufs;
for(i = 0; i < ethptr->rxRingSize; i++) {
rdescptr->next = rdescptr + 1;
rdescptr->buffer = (uint32)pktptr->net_ethdst;
rdescptr->buflen = ETH_BUF_SIZE;
rdescptr->bufoff = 0;
rdescptr->stat = ETH_AM335X_RDS_OWN;
rdescptr++;
pktptr++;
}
(--rdescptr)->next = NULL;
ethptr->rxHead = 0;
ethptr->rxTail = 0;
ethptr->isem = semcreate(0);
if((int32)ethptr->isem == SYSERR) {
return SYSERR;
}
/* initialize the tx ring size */
ethptr->txRingSize = ETH_AM335X_TX_RING_SIZE;
/* Allocate memory for tx ring */
ethptr->txRing = (void*)getmem(sizeof(struct eth_a_tx_desc)*
ethptr->txRingSize);
if((int32)ethptr->txRing == SYSERR) {
return SYSERR;
}
/* Zero out the tx ring */
memset((char*)ethptr->txRing, NULLCH,
sizeof(struct eth_a_tx_desc)*ethptr->txRingSize);
/* Allocate memory for tx buffers */
ethptr->txBufs = (void*)getmem(ETH_BUF_SIZE *
ethptr->txRingSize);
if((int32)ethptr->txBufs == SYSERR) {
return SYSERR;
}
/* Zero out the tx buffers */
memset((char*)ethptr->txBufs, NULLCH, ETH_BUF_SIZE *
ethptr->txRingSize);
/* Initialize the tx ring */
tdescptr = (struct eth_a_tx_desc *)ethptr->txRing;
pktptr = (struct netpacket *)ethptr->txBufs;
for(i = 0; i < ethptr->txRingSize; i++) {
tdescptr->next = NULL;
tdescptr->buffer = (uint32)pktptr->net_ethdst;
tdescptr->buflen = ETH_BUF_SIZE;
tdescptr->bufoff = 0;
tdescptr->stat = (ETH_AM335X_TDS_SOP |
ETH_AM335X_TDS_EOP |
ETH_AM335X_TDS_DIR |
ETH_AM335X_TDS_P1);
tdescptr++;
pktptr++;
}
ethptr->txHead = 0;
ethptr->txTail = 0;
ethptr->osem = semcreate(ethptr->txRingSize);
if((int32)ethptr->osem == SYSERR) {
return SYSERR;
}
/* Enable the ALE and put it into bypass mode */
csrptr->ale->ctrl = (ETH_AM335X_ALECTL_EN |
ETH_AM335X_ALECTL_BY);
/* Put the ports 0, 1 in forwarding state */
csrptr->ale->portctl[0] = ETH_AM335X_ALEPCTL_FWD;
csrptr->ale->portctl[1] = ETH_AM335X_ALEPCTL_FWD;
/* Start the rx and tx processes in DMA */
csrptr->cpdma->tx_ctrl = 1;
csrptr->cpdma->rx_ctrl = 1;
/* Initialize the head desc pointers for tx and rx */
csrptr->stateram->tx_hdp[0] = 0;
csrptr->stateram->rx_hdp[0] = (uint32)ethptr->rxRing;
/* Enable Rx and Tx in MAC */
csrptr->sl->macctrl |= ETH_AM335X_SLCTL_EN;
/* Set interrupt vectors */
set_evec(ETH_AM335X_TXINT, (uint32)devptr->dvintr);
set_evec(ETH_AM335X_RXINT, (uint32)devptr->dvintr);
/* Enable the CPDMA interrupts */
csrptr->cpdma->tx_intmask_set = 0x1;
csrptr->cpdma->rx_intmask_set = 0x1;
/* Route the interrupts to core 0 */
csrptr->wr->c0_tx_en = 0x1;
csrptr->wr->c0_rx_en = 0x1;
return OK;
}

69
device/eth/ethread.c

@ -0,0 +1,69 @@
/* ethread.c - ethread */
#include <xinu.h>
/*------------------------------------------------------------------------
* ethread - read an incoming packet on TI AM335X Ethernet
*------------------------------------------------------------------------
*/
int32 ethread (
struct dentry *devptr,
void *buf,
uint32 count
)
{
struct ethcblk *ethptr; /* Ethernet ctl blk ptr */
struct eth_a_csreg *csrptr; /* Ethernet CSR pointer */
struct eth_a_rx_desc *rdescptr;/* Rx Desc. pointer */
struct eth_a_rx_desc *prev; /* Prev Rx desc pointer */
uint32 retval; /* Num of bytes returned*/
ethptr = &ethertab[devptr->dvminor];
/* Get the pointer to Ethernet CSR */
csrptr = (struct eth_a_csreg *)ethptr->csr;
/* Wait for a packet */
wait(ethptr->isem);
/* Get pointer to the descriptor */
rdescptr = (struct eth_a_rx_desc *)ethptr->rxRing +
ethptr->rxHead;
/* Read the packet length */
retval = rdescptr->packlen;
if(retval > count) {
retval = count;
}
/* Copy the packet into user provided buffer */
memcpy((char *)buf, (char *)rdescptr->buffer, retval);
/* Initialize the descriptor for next packet */
rdescptr->stat = ETH_AM335X_RDS_OWN;
rdescptr->bufoff = 0;
rdescptr->buflen = ETH_BUF_SIZE;
rdescptr->packlen = 0;
rdescptr->next = NULL;
/* Insert the descriptor into Rx queue */
prev = (struct eth_a_rx_desc *)csrptr->stateram->rx_hdp[0];
if(prev == NULL) {
kprintf("hdp 0, adding %x\n", rdescptr);
csrptr->stateram->rx_hdp[0] = (uint32)rdescptr;
}
else {
while(prev->next != NULL) {
prev = prev->next;
}
prev->next = rdescptr;
}
/* Increment the head index of rx ring */
ethptr->rxHead++;
if(ethptr->rxHead >= ethptr->rxRingSize) {
ethptr->rxHead = 0;
}
return retval;
}

84
device/eth/ethwrite.c

@ -0,0 +1,84 @@
/* ethwrite.c - ethwrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* ethwrite - enqueue a packet for transmission on TI AM335X Ethernet
*------------------------------------------------------------------------
*/
int32 ethwrite (
struct dentry *devptr,
void *buf,
uint32 count
)
{
struct ethcblk *ethptr; /* Ether entry pointer */
struct eth_a_csreg *csrptr; /* Ethernet CSR pointer */
struct eth_a_tx_desc *tdescptr;/* Tx Desc. pointer */
struct eth_a_tx_desc *prev; /* Prev. Desc. pointer */
ethptr = &ethertab[devptr->dvminor];
/* Get the pointer to the Ethernet CSR */
csrptr = (struct eth_a_csreg *)ethptr->csr;
/* Wait for an empty slot in the queue */
wait(ethptr->osem);
/* Get the pointer to the next descriptor */
tdescptr = (struct eth_a_tx_desc *)ethptr->txRing +
ethptr->txTail;
/* Adjust count if greater than max. possible packet size */
if(count > PACKLEN) {
count = PACKLEN;
}
/* Initialize the descriptor */
tdescptr->next = NULL;
tdescptr->buflen = count;
tdescptr->bufoff = 0;
tdescptr->packlen = count;
tdescptr->stat = (ETH_AM335X_TDS_SOP | /* Start of packet */
ETH_AM335X_TDS_EOP | /* End of packet */
ETH_AM335X_TDS_OWN | /* Own flag set for DMA */
ETH_AM335X_TDS_DIR | /* Directed packet */
ETH_AM335X_TDS_P1); /* Output port is port1 */
/* Copy the packet into the Tx buffer */
memcpy((char *)tdescptr->buffer, buf, count);
/* TODO Figure out why we need this hack */
/* This ethernet device does not send packets smaller than 60 */
/* bytes; So pad a small packet to make it 60 bytes long */
if(count < 60) {
memset((char *)tdescptr->buffer+count, 0, 60-count);
tdescptr->buflen = 60;
tdescptr->packlen = 60;
}
/* Insert the descriptor into Tx queue */
if(csrptr->stateram->tx_hdp[0] == 0) {
/* Tx queue is empty, this desc. will be the first */
csrptr->stateram->tx_hdp[0] = (uint32)tdescptr;
}
else {
/* Tx queue not empty, insert at end */
prev = (struct eth_a_tx_desc *)
csrptr->stateram->tx_hdp[0];
while(prev->next != NULL) {
prev = prev->next;
}
prev->next = tdescptr;
}
/* Increment the tail index of the Tx ring */
ethptr->txTail++;
if(ethptr->txTail >= ethptr->txRingSize) {
ethptr->txTail = 0;
}
return count;
}

40
device/lfs/lfdballoc.c

@ -0,0 +1,40 @@
/* lfdballoc.c - lfdballoc */
#include <xinu.h>
#define DFILL '+' /* character used to fill a disk block */
/*------------------------------------------------------------------------
* lfdballoc - Allocate a new data block from free list on disk
* (assumes directory mutex held)
*------------------------------------------------------------------------
*/
dbid32 lfdballoc (
struct lfdbfree *dbuff /* Addr. of buffer to hold data block */
)
{
dbid32 dnum; /* ID of next d-block on the free list */
int32 retval; /* Return value */
/* Get the ID of first data block on the free list */
dnum = Lf_data.lf_dir.lfd_dfree;
if (dnum == LF_DNULL) { /* Ran out of free data blocks */
panic("out of data blocks");
}
retval = read(Lf_data.lf_dskdev, (char *)dbuff, dnum);
if (retval == SYSERR) {
panic("lfdballoc cannot read disk block\n\r");
}
/* Unlink d-block from in-memory directory */
Lf_data.lf_dir.lfd_dfree = dbuff->lf_nextdb;
write(Lf_data.lf_dskdev, (char *)&Lf_data.lf_dir, LF_AREA_DIR);
Lf_data.lf_dirdirty = FALSE;
/* Fill data block to erase old data */
memset((char *)dbuff, DFILL, LF_BLKSIZ);
return dnum;
}

25
device/lfs/lfdbfree.c

@ -0,0 +1,25 @@
/* lfdbfree.c - lfdbfree */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfdbfree - Free a data block given its block number (assumes
* directory mutex is held)
*------------------------------------------------------------------------
*/
status lfdbfree(
did32 diskdev, /* ID of disk device to use */
dbid32 dnum /* ID of data block to free */
)
{
struct lfdir *dirptr; /* Pointer to directory */
struct lfdbfree buf; /* Buffer to hold data block */
dirptr = &Lf_data.lf_dir;
buf.lf_nextdb = dirptr->lfd_dfree;
dirptr->lfd_dfree = dnum;
write(diskdev, (char *)&buf, dnum);
write(diskdev, (char *)dirptr, LF_AREA_DIR);
return OK;
}

42
device/lfs/lfflush.c

@ -0,0 +1,42 @@
/* lfflush.c - lfflush */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfflush - Flush directory, data block, and index block for an open
* file (assumes file mutex is held)
*------------------------------------------------------------------------
*/
status lfflush (
struct lflcblk *lfptr /* Ptr to file pseudo device */
)
{
if (lfptr->lfstate == LF_FREE) {
return SYSERR;
}
/* Write the directory if it has changed */
if (Lf_data.lf_dirdirty) {
write(Lf_data.lf_dskdev, (char *)&Lf_data.lf_dir,
LF_AREA_DIR);
Lf_data.lf_dirdirty = FALSE;
}
/* Write data block if it has changed */
if (lfptr->lfdbdirty) {
write(Lf_data.lf_dskdev, lfptr->lfdblock, lfptr->lfdnum);
lfptr->lfdbdirty = FALSE;
}
/* Write i-block if it has changed */
if (lfptr->lfibdirty) {
lfibput(Lf_data.lf_dskdev, lfptr->lfinum, &lfptr->lfiblock);
lfptr->lfibdirty = FALSE;
}
return OK;
}

61
device/lfs/lfgetmode.c

@ -0,0 +1,61 @@
/* lfgetmode.c - lfgetmode */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfgetmode - Parse mode argument and generate integer of mode bits
*------------------------------------------------------------------------
*/
int32 lfgetmode (
char *mode /* String of mode characters */
)
{
int32 mbits; /* Mode bits to return */
char ch; /* Next char in mode string */
mbits = 0;
/* Mode string specifies: */
/* r - read */
/* w - write */
/* o - old (file must exist) */
/* n - new (create a new file) */
while ( (ch = *mode++) != NULLCH) {
switch (ch) {
case 'r': if (mbits&LF_MODE_R) {
return SYSERR;
}
mbits |= LF_MODE_R;
continue;
case 'w': if (mbits&LF_MODE_W) {
return SYSERR;
}
mbits |= LF_MODE_W;
continue;
case 'o': if (mbits&LF_MODE_O || mbits&LF_MODE_N) {
return SYSERR;
}
mbits |= LF_MODE_O;
break;
case 'n': if (mbits&LF_MODE_O || mbits&LF_MODE_N) {
return SYSERR;
}
mbits |= LF_MODE_N;
break;
default: return SYSERR;
}
}
/* If neither read nor write specified, allow both */
if ( (mbits&LF_MODE_RW) == 0 ) {
mbits |= LF_MODE_RW;
}
return mbits;
}

33
device/lfs/lfiballoc.c

@ -0,0 +1,33 @@
/* lfiballoc.c - lfiballoc */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfiballoc - Allocate a new index block from free list on disk
* (assumes directory mutex held)
*------------------------------------------------------------------------
*/
ibid32 lfiballoc (void)
{
ibid32 ibnum; /* ID of next block on the free list */
struct lfiblk iblock; /* Buffer to hold an index block */
/* Get ID of first index block on free list */
ibnum = Lf_data.lf_dir.lfd_ifree;
if (ibnum == LF_INULL) { /* Ran out of free index blocks */
panic("out of index blocks");
}
lfibget(Lf_data.lf_dskdev, ibnum, &iblock);
/* Unlink index block from the directory free list */
Lf_data.lf_dir.lfd_ifree = iblock.ib_next;
/* Write a copy of the directory to disk after the change */
write(Lf_data.lf_dskdev, (char *) &Lf_data.lf_dir, LF_AREA_DIR);
Lf_data.lf_dirdirty = FALSE;
return ibnum;
}

22
device/lfs/lfibclear.c

@ -0,0 +1,22 @@
/* lfibclear.c - lfibclear */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfibclear -- Clear an in-core copy of an index block
*------------------------------------------------------------------------
*/
void lfibclear(
struct lfiblk *ibptr, /* Address of i-block in memory */
int32 offset /* File offset for this i-block */
)
{
int32 i; /* Index for data block array */
ibptr->ib_offset = offset; /* Assign specified file offset */
for (i=0 ; i<LF_IBLEN ; i++) { /* Clear each data block pointer*/
ibptr->ib_dba[i] = LF_DNULL;
}
ibptr->ib_next = LF_INULL; /* Set next ptr to null */
return;
}

31
device/lfs/lfibget.c

@ -0,0 +1,31 @@
/* lfibget.c - lfibget */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfibget - Get an index block from disk given its number (assumes
* mutex is held)
*------------------------------------------------------------------------
*/
void lfibget(
did32 diskdev, /* Device ID of disk to use */
ibid32 inum, /* ID of index block to fetch */
struct lfiblk *ibuff /* Buffer to hold index block */
)
{
char *from, *to; /* Pointers used in copying */
int32 i; /* Loop index used during copy */
char dbuff[LF_BLKSIZ]; /* Buffer to hold disk block */
/* Read disk block that contains the specified index block */
read(diskdev, dbuff, ib2sect(inum));
/* Copy specified index block to caller's ibuff */
from = dbuff + ib2disp(inum);
to = (char *)ibuff;
for (i=0 ; i<sizeof(struct lfiblk) ; i++)
*to++ = *from++;
return;
}

43
device/lfs/lfibput.c

@ -0,0 +1,43 @@
/* lfibput.c - lfibput */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfibput - Write an index block to disk given its ID (assumes
* mutex is held)
*------------------------------------------------------------------------
*/
status lfibput(
did32 diskdev, /* ID of disk device */
ibid32 inum, /* ID of index block to write */
struct lfiblk *ibuff /* Buffer holding the index blk */
)
{
dbid32 diskblock; /* ID of disk sector (block) */
char *from, *to; /* Pointers used in copying */
int32 i; /* Loop index used during copy */
char dbuff[LF_BLKSIZ]; /* Temp. buffer to hold d-block */
/* Compute disk block number and offset of index block */
diskblock = ib2sect(inum);
to = dbuff + ib2disp(inum);
from = (char *)ibuff;
/* Read disk block */
if (read(diskdev, dbuff, diskblock) == SYSERR) {
return SYSERR;
}
/* Copy index block into place */
for (i=0 ; i<sizeof(struct lfiblk) ; i++) {
*to++ = *from++;
}
/* Write the block back to disk */
write(diskdev, dbuff, diskblock);
return OK;
}

38
device/lfs/lflclose.c

@ -0,0 +1,38 @@
/* lflclose.c - lflclose.c */
#include <xinu.h>
/*------------------------------------------------------------------------
* lflclose - Close a file by flushing output and freeing device entry
*------------------------------------------------------------------------
*/
devcall lflclose (
struct dentry *devptr /* Entry in device switch table */
)
{
struct lflcblk *lfptr; /* Ptr to open file table entry */
/* Obtain exclusive use of the file */
lfptr = &lfltab[devptr->dvminor];
wait(lfptr->lfmutex);
/* If file is not open, return an error */
if (lfptr->lfstate != LF_USED) {
signal(lfptr->lfmutex);
return SYSERR;
}
/* Write index or data blocks to disk if they have changed */
if (Lf_data.lf_dirdirty || lfptr->lfdbdirty || lfptr->lfibdirty) {
lfflush(lfptr);
}
/* Set device state to FREE and return to caller */
lfptr->lfstate = LF_FREE;
signal(lfptr->lfmutex);
return OK;
}

47
device/lfs/lflcontrol.c

@ -0,0 +1,47 @@
/* lflcontrol.c - lflcontrol */
#include <xinu.h>
/*------------------------------------------------------------------------
* lflcontrol - Provide control functions for a local file pseudo-device
*------------------------------------------------------------------------
*/
devcall lflcontrol (
struct dentry *devptr, /* Entry in device switch table */
int32 func, /* A control function */
int32 arg1, /* Argument #1 */
int32 arg2 /* Argument #2 */
)
{
struct lflcblk *lfptr; /* Ptr to open file table entry */
int32 retval; /* Return value from func. call */
/* Obtain exclusive use of the file */
lfptr = &lfltab[devptr->dvminor];
wait(lfptr->lfmutex);
/* If file is not open, return an error */
if (lfptr->lfstate != LF_USED) {
signal(lfptr->lfmutex);
return SYSERR;
}
switch (func) {
/* Truncate a file */
case LF_CTL_TRUNC:
wait(Lf_data.lf_mutex);
retval = lftruncate(lfptr);
signal(Lf_data.lf_mutex);
signal(lfptr->lfmutex);
return retval;
default:
kprintf("lfcontrol: function %d not valid\n\r", func);
signal(lfptr->lfmutex);
return SYSERR;
}
}

52
device/lfs/lflgetc.c

@ -0,0 +1,52 @@
/* lflgetc.c - lfgetc */
#include <xinu.h>
/*------------------------------------------------------------------------
* lflgetc - Read the next byte from an open local file
*------------------------------------------------------------------------
*/
devcall lflgetc (
struct dentry *devptr /* Entry in device switch table */
)
{
struct lflcblk *lfptr; /* Ptr to open file table entry */
struct ldentry *ldptr; /* Ptr to file's entry in the */
/* in-memory directory */
int32 onebyte; /* Next data byte in the file */
/* Obtain exclusive use of the file */
lfptr = &lfltab[devptr->dvminor];
wait(lfptr->lfmutex);
/* If file is not open, return an error */
if (lfptr->lfstate != LF_USED) {
signal(lfptr->lfmutex);
return SYSERR;
}
/* Return EOF for any attempt to read beyond the end-of-file */
ldptr = lfptr->lfdirptr;
if (lfptr->lfpos >= ldptr->ld_size) {
signal(lfptr->lfmutex);
return EOF;
}
/* If byte pointer is beyond the current data block, set up */
/* a new data block */
if (lfptr->lfbyte >= &lfptr->lfdblock[LF_BLKSIZ]) {
lfsetup(lfptr);
}
/* Extract the next byte from block, update file position, and */
/* return the byte to the caller */
onebyte = 0xff & *lfptr->lfbyte++;
lfptr->lfpos++;
signal(lfptr->lfmutex);
return onebyte;
}

46
device/lfs/lflinit.c

@ -0,0 +1,46 @@
/* lflinit.c - lflinit */
#include <xinu.h>
struct lflcblk lfltab[Nlfl]; /* Pseudo-device control blocks */
/*------------------------------------------------------------------------
* lflinit - Initialize control blocks for local file pseudo-devices
*------------------------------------------------------------------------
*/
devcall lflinit (
struct dentry *devptr /* Entry in device switch table */
)
{
struct lflcblk *lfptr; /* Ptr. to control block entry */
int32 i; /* Walks through name array */
lfptr = &lfltab[ devptr->dvminor ];
/* Initialize control block entry */
lfptr->lfstate = LF_FREE; /* Device is currently unused */
lfptr->lfdev = devptr->dvnum; /* Set device ID */
lfptr->lfmutex = semcreate(1); /* Create the mutex semaphore */
/* Initialize the directory and file position */
lfptr->lfdirptr = (struct ldentry *) NULL;
lfptr->lfpos = 0;
for (i=0; i<LF_NAME_LEN; i++) {
lfptr->lfname[i] = NULLCH;
}
/* Zero the in-memory index block and data block */
lfptr->lfinum = LF_INULL;
memset((char *) &lfptr->lfiblock, NULLCH, sizeof(struct lfiblk));
lfptr->lfdnum = 0;
memset((char *) &lfptr->lfdblock, NULLCH, LF_BLKSIZ);
/* Start with the byte beyond the current data block */
lfptr->lfbyte = &lfptr->lfdblock[LF_BLKSIZ];
lfptr->lfibdirty = lfptr->lfdbdirty = FALSE;
return OK;
}

64
device/lfs/lflputc.c

@ -0,0 +1,64 @@
/* lflputc.c - lfputc */
#include <xinu.h>
/*------------------------------------------------------------------------
* lflputc - Write a single byte to an open local file
*------------------------------------------------------------------------
*/
devcall lflputc (
struct dentry *devptr, /* Entry in device switch table */
char ch /* Character (byte) to write */
)
{
struct lflcblk *lfptr; /* Ptr to open file table entry */
struct ldentry *ldptr; /* Ptr to file's entry in the */
/* in-memory directory */
/* Obtain exclusive use of the file */
lfptr = &lfltab[devptr->dvminor];
wait(lfptr->lfmutex);
/* If file is not open, return an error */
if (lfptr->lfstate != LF_USED) {
signal(lfptr->lfmutex);
return SYSERR;
}
/* Return SYSERR for an attempt to skip bytes beyond the byte */
/* that is currently the end of the file */
ldptr = lfptr->lfdirptr;
if (lfptr->lfpos > ldptr->ld_size) {
signal(lfptr->lfmutex);
return SYSERR;
}
/* If pointer is outside current block, set up new block */
if (lfptr->lfbyte >= &lfptr->lfdblock[LF_BLKSIZ]) {
/* Set up block for current file position */
lfsetup(lfptr);
}
/* If appending a byte to the file, increment the file size. */
/* Note: comparison might be equal, but should not be greater.*/
if (lfptr->lfpos >= ldptr->ld_size) {
ldptr->ld_size++;
Lf_data.lf_dirdirty = TRUE;
}
/* Place byte in buffer and mark buffer "dirty" */
*lfptr->lfbyte++ = ch;
lfptr->lfpos++;
lfptr->lfdbdirty = TRUE;
signal(lfptr->lfmutex);
return OK;
}

39
device/lfs/lflread.c

@ -0,0 +1,39 @@
/* lflread.c - lflread */
#include <xinu.h>
/*------------------------------------------------------------------------
* lflread - Read from a previously opened local file
*------------------------------------------------------------------------
*/
devcall lflread (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer to hold bytes */
int32 count /* Max bytes to read */
)
{
uint32 numread; /* Number of bytes read */
int32 nxtbyte; /* Character or SYSERR/EOF */
if (count < 0) {
return SYSERR;
}
/* Iterate and use lflgetc to read individual bytes */
for (numread=0 ; numread < count ; numread++) {
nxtbyte = lflgetc(devptr);
if (nxtbyte == SYSERR) {
return SYSERR;
} else if (nxtbyte == EOF) { /* EOF before finished */
if (numread == 0) {
return EOF;
} else {
return numread;
}
} else {
*buff++ = (char) (0xff & nxtbyte);
}
}
return numread;
}

41
device/lfs/lflseek.c

@ -0,0 +1,41 @@
/* lflseek.c - lflseek */
#include <xinu.h>
/*------------------------------------------------------------------------
* lflseek - Seek to a specified position in a file
*------------------------------------------------------------------------
*/
devcall lflseek (
struct dentry *devptr, /* Entry in device switch table */
uint32 offset /* Byte position in the file */
)
{
struct lflcblk *lfptr; /* Ptr to open file table entry */
/* If file is not open, return an error */
lfptr = &lfltab[devptr->dvminor];
wait(lfptr->lfmutex);
if (lfptr->lfstate != LF_USED) {
signal(lfptr->lfmutex);
return SYSERR;
}
/* Verify offset is within current file size */
if (offset > lfptr->lfdirptr->ld_size) {
signal(lfptr->lfmutex);
return SYSERR;
}
/* Record new offset and invalidate byte pointer (i.e., force */
/* the index and data blocks to be replaced if a successive */
/* call is made to read or write) */
lfptr->lfpos = offset;
lfptr->lfbyte = &lfptr->lfdblock[LF_BLKSIZ];
signal(lfptr->lfmutex);
return OK;
}

29
device/lfs/lflwrite.c

@ -0,0 +1,29 @@
/* lflwrite.c - lflwrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* lflwrite -- Write data to a previously opened local disk file
*------------------------------------------------------------------------
*/
devcall lflwrite (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer holding data to write */
int32 count /* Number of bytes to write */
)
{
int32 i; /* Number of bytes written */
if (count < 0) {
return SYSERR;
}
/* Iteratate and write one byte at a time */
for (i=0; i<count; i++) {
if (lflputc(devptr, *buff++) == SYSERR) {
return SYSERR;
}
}
return count;
}

40
device/lfs/lfscheck.c

@ -0,0 +1,40 @@
/* lfscheck.c - lfscheck */
#include <xinu.h>
#include <ramdisk.h>
/*------------------------------------------------------------------------
* lfscheck - Check a directory to verify it contains a Xinu file system
*------------------------------------------------------------------------
*/
status lfscheck (
struct lfdir *dirptr /* Ptr to an in-core directory */
)
{
uint32 reverse; /* LFS_ID in reverse byte order */
/* Verify the File System ID, all 0's and all 1's fields */
if ( (dirptr->lfd_fsysid != LFS_ID) ||
(dirptr->lfd_allzeros != 0x00000000) ||
(dirptr->lfd_allones != 0xffffffff) ) {
return SYSERR;
}
/* Check the reverse-order File System ID field */
reverse = ((LFS_ID>>24) & 0x000000ff) |
((LFS_ID>> 8) & 0x0000ff00) |
((LFS_ID<< 8) & 0x00ff0000) |
((LFS_ID<<24) & 0xff000000) ;
if (dirptr->lfd_revid != reverse) {
return SYSERR;
}
/* Extra sanity check - verify file count is positive */
if (dirptr->lfd_nfiles < 0){
return SYSERR;
}
return OK;
}

65
device/lfs/lfsckfmt.c

@ -0,0 +1,65 @@
/* lfckfmt.c - lfckfmt */
#include <xinu.h>
#include <ramdisk.h>
/*------------------------------------------------------------------------
* lfckfmt - Check the format of an initially-created disk
*------------------------------------------------------------------------
*/
status lfsckfmt (
did32 disk /* ID of an open disk device */
)
{
uint32 ibsectors; /* Number of sectors of i-blocks*/
struct lfdir dir; /* Buffer to hold the directory */
uint32 dblks; /* Total free data blocks */
struct lfiblk iblock; /* Space for one i-block */
struct lfdbfree dblock; /* Data block on the free list */
int32 lfiblks; /* Total free index blocks */
int32 retval;
ibid32 nextib;
dbid32 nextdb;
/* Read directory */
retval = read(disk,(char *)&dir, LF_AREA_DIR);
if (retval == SYSERR) {
panic("cannot read directory");
}
kprintf("Have read directory from disk device %d\n\r",
disk);
/* Check to see if directory contains a Xinu file system */
if (lfscheck(&dir) == SYSERR) {
panic("directory does not contain a Xinu file system");
}
kprintf("Directory corresponds to a local Xinu file system\n");
/* Follow index block list */
lfiblks = 0;
nextib = dir.lfd_ifree;
kprintf("initial index block is %d\n\r", nextib);
while (nextib != LF_INULL) {
lfiblks++;
lfibget(disk, nextib, &iblock);
nextib = iblock.ib_next;
}
ibsectors = (lfiblks + 6) /7;
kprintf("Found %d index blocks (%d sectors)\n\r", lfiblks, ibsectors);
/* Follow data block list */
dblks = 0;
nextdb = dir.lfd_dfree;
kprintf("initial data block is %d\n\r", nextdb);
while (nextdb != LF_DNULL) {
dblks++;
read(disk, (char *)&dblock, nextdb);
nextdb = dblock.lf_nextdb;
}
kprintf("Found %d data blocks\n\r", dblks);
return OK;
}

74
device/lfs/lfscreate.c

@ -0,0 +1,74 @@
/* lfscreate.c - lfscreate */
#include <xinu.h>
#include <ramdisk.h>
/*------------------------------------------------------------------------
* lfscreate - Create an initially-empty file system on a disk
*------------------------------------------------------------------------
*/
status lfscreate (
did32 disk, /* ID of an open disk device */
ibid32 lfiblks, /* Num. of index blocks on disk */
uint32 dsiz /* Total size of disk in bytes */
)
{
uint32 sectors; /* Number of sectors to use */
uint32 ibsectors; /* Number of sectors of i-blocks*/
uint32 ibpersector; /* Number of i-blocks per sector*/
struct lfdir dir; /* Buffer to hold the directory */
uint32 dblks; /* Total free data blocks */
struct lfiblk iblock; /* Space for one i-block */
struct lfdbfree dblock; /* Data block on the free list */
dbid32 dbindex; /* Index for data blocks */
int32 retval; /* Return value from func call */
int32 i; /* Loop index */
/* Compute total sectors on disk */
sectors = dsiz / LF_BLKSIZ; /* Truncate to full sector */
/* Compute number of sectors comprising i-blocks */
ibpersector = LF_BLKSIZ / sizeof(struct lfiblk);
ibsectors = (lfiblks+(ibpersector-1)) / ibpersector;/* Round up */
lfiblks = ibsectors * ibpersector;
if (ibsectors > sectors/2) { /* Invalid arguments */
return SYSERR;
}
/* Create an initial directory */
memset((char *)&dir, NULLCH, sizeof(struct lfdir));
dir.lfd_nfiles = 0;
dbindex= (dbid32)(ibsectors + 1);
dir.lfd_dfree = dbindex;
dblks = sectors - ibsectors - 1;
retval = write(disk,(char *)&dir, LF_AREA_DIR);
if (retval == SYSERR) {
return SYSERR;
}
/* Create list of free i-blocks on disk */
lfibclear(&iblock, 0);
for (i=0; i<lfiblks-1; i++) {
iblock.ib_next = (ibid32)(i + 1);
lfibput(disk, i, &iblock);
}
iblock.ib_next = LF_INULL;
lfibput(disk, i, &iblock);
/* Create list of free data blocks on disk */
memset((char*)&dblock, NULLCH, LF_BLKSIZ);
for (i=0; i<dblks-1; i++) {
dblock.lf_nextdb = dbindex + 1;
write(disk, (char *)&dblock, dbindex);
dbindex++;
}
dblock.lf_nextdb = LF_DNULL;
write(disk, (char *)&dblock, dbindex);
close(disk);
return OK;
}

122
device/lfs/lfsetup.c

@ -0,0 +1,122 @@
/* lfsetup.c - lfsetup */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfsetup - Set a file's index block and data block for the current
* file position (assumes file mutex held)
*------------------------------------------------------------------------
*/
status lfsetup (
struct lflcblk *lfptr /* Pointer to slave file device */
)
{
dbid32 dnum; /* Data block to fetch */
ibid32 ibnum; /* I-block number during search */
struct ldentry *ldptr; /* Ptr to file entry in dir. */
struct lfiblk *ibptr; /* Ptr to in-memory index block */
uint32 newoffset; /* Computed data offset for */
/* next index block */
int32 dindex; /* Index into array in an index */
/* block */
/* Obtain exclusive access to the directory */
wait(Lf_data.lf_mutex);
/* Get pointers to in-memory directory, file's entry in the */
/* directory, and the in-memory index block */
ldptr = lfptr->lfdirptr;
ibptr = &lfptr->lfiblock;
/* If existing index block or data block changed, write to disk */
if (lfptr->lfibdirty || lfptr->lfdbdirty) {
lfflush(lfptr);
}
ibnum = lfptr->lfinum; /* Get ID of curr. index block */
/* If there is no index block in memory (e.g., because the file */
/* was just opened), either load the first index block of */
/* the file or allocate a new first index block */
if (ibnum == LF_INULL) {
/* Check directory entry to see if index block exists */
ibnum = ldptr->ld_ilist;
if (ibnum == LF_INULL) { /* Empty file - get new i-block*/
ibnum = lfiballoc();
lfibclear(ibptr, 0);
ldptr->ld_ilist = ibnum;
lfptr->lfibdirty = TRUE;
} else { /* Nonempty - read first i-block*/
lfibget(Lf_data.lf_dskdev, ibnum, ibptr);
}
lfptr->lfinum = ibnum;
/* Otherwise, if current file position has been moved to an */
/* offset before the current index block, start at the */
/* beginning of the index list for the file */
} else if (lfptr->lfpos < ibptr->ib_offset) {
/* Load initial index block for the file (we know that */
/* at least one index block exists) */
ibnum = ldptr->ld_ilist;
lfibget(Lf_data.lf_dskdev, ibnum, ibptr);
lfptr->lfinum = ibnum;
}
/* At this point, an index block is in memory, but may cover */
/* an offset less than the current file position. Loop until */
/* the index block covers the current file position. */
while ((lfptr->lfpos & ~LF_IMASK) > ibptr->ib_offset ) {
ibnum = ibptr->ib_next;
if (ibnum == LF_INULL) {
/* Allocate new index block to extend file */
ibnum = lfiballoc();
ibptr->ib_next = ibnum;
lfibput(Lf_data.lf_dskdev, lfptr->lfinum, ibptr);
lfptr->lfinum = ibnum;
newoffset = ibptr->ib_offset + LF_IDATA;
lfibclear(ibptr, newoffset);
lfptr->lfibdirty = TRUE;
} else {
lfibget(Lf_data.lf_dskdev, ibnum, ibptr);
lfptr->lfinum = ibnum;
}
lfptr->lfdnum = LF_DNULL; /* Invalidate old data block */
}
/* At this point, the index block in lfiblock covers the */
/* current file position (i.e., position lfptr->lfpos). The */
/* next step consists of loading the correct data block. */
dindex = (lfptr->lfpos & LF_IMASK) >> 9;
/* If data block index does not match current data block, read */
/* the correct data block from disk */
dnum = lfptr->lfiblock.ib_dba[dindex];
if (dnum == LF_DNULL) { /* Allocate new data block */
dnum = lfdballoc((struct lfdbfree *)&lfptr->lfdblock);
lfptr->lfiblock.ib_dba[dindex] = dnum;
lfptr->lfibdirty = TRUE;
} else if ( dnum != lfptr->lfdnum) {
read(Lf_data.lf_dskdev, (char *)lfptr->lfdblock, dnum);
lfptr->lfdbdirty = FALSE;
}
lfptr->lfdnum = dnum;
/* Use current file offset to set the pointer to the next byte */
/* within the data block */
lfptr->lfbyte = &lfptr->lfdblock[lfptr->lfpos & LF_DMASK];
signal(Lf_data.lf_mutex);
return OK;
}

32
device/lfs/lfsinit.c

@ -0,0 +1,32 @@
/* lfsinit.c - lfsinit */
#include <xinu.h>
struct lfdata Lf_data;
/*------------------------------------------------------------------------
* lfsinit - Initialize the local file system master device
*------------------------------------------------------------------------
*/
devcall lfsinit (
struct dentry *devptr /* Entry in device switch table */
)
{
/* Assign ID of disk device that will be used */
Lf_data.lf_dskdev = LF_DISK_DEV;
/* Create a mutual exclusion semaphore */
Lf_data.lf_mutex = semcreate(1);
/* Zero directory area (for debugging) */
memset((char *)&Lf_data.lf_dir, NULLCH, sizeof(struct lfdir));
/* Initialize directory to "not present" in memory */
Lf_data.lf_dirpresent = Lf_data.lf_dirdirty = FALSE;
return OK;
}

185
device/lfs/lfsopen.c

@ -0,0 +1,185 @@
/* lfsopen.c - lfsopen */
#include <xinu.h>
/*------------------------------------------------------------------------
* lfsopen - Open a file and allocate a local file pseudo-device
*------------------------------------------------------------------------
*/
devcall lfsopen (
struct dentry *devptr, /* Entry in device switch table */
char *name, /* Name of file to open */
char *mode /* Mode chars: 'r' 'w' 'o' 'n' */
)
{
struct lfdir *dirptr; /* Ptr to in-memory directory */
char *from, *to; /* Ptrs used during copy */
char *nam, *cmp; /* Ptrs used during comparison */
int32 i; /* General loop index */
did32 lfnext; /* Minor number of an unused */
/* file pseudo-device */
struct ldentry *ldptr; /* Ptr to an entry in directory */
struct lflcblk *lfptr; /* Ptr to open file table entry */
bool8 found; /* Was the name found? */
int32 retval; /* Value returned from function */
int32 mbits; /* Mode bits */
/* Check length of name file (leaving space for NULLCH */
from = name;
for (i=0; i< LF_NAME_LEN; i++) {
if (*from++ == NULLCH) {
break;
}
}
if (i >= LF_NAME_LEN) { /* Name is too long */
return SYSERR;
}
/* Parse mode argument and convert to binary */
mbits = lfgetmode(mode);
if (mbits == SYSERR) {
return SYSERR;
}
/* If named file is already open, return SYSERR */
lfnext = SYSERR;
for (i=0; i<Nlfl; i++) { /* Search file pseudo-devices */
lfptr = &lfltab[i];
if (lfptr->lfstate == LF_FREE) {
if (lfnext == SYSERR) {
lfnext = i; /* Record index */
}
continue;
}
/* Compare requested name to name of open file */
nam = name;
cmp = lfptr->lfname;
while(*nam != NULLCH) {
if (*nam != *cmp) {
break;
}
nam++;
cmp++;
}
/* See if comparison succeeded */
if ( (*nam==NULLCH) && (*cmp == NULLCH) ) {
return SYSERR;
}
}
if (lfnext == SYSERR) { /* No slave file devices are available */
return SYSERR;
}
/* Obtain copy of directory if not already present in memory */
dirptr = &Lf_data.lf_dir;
wait(Lf_data.lf_mutex);
if (! Lf_data.lf_dirpresent) {
retval = read(Lf_data.lf_dskdev,(char *)dirptr,LF_AREA_DIR);
if (retval == SYSERR ) {
signal(Lf_data.lf_mutex);
return SYSERR;
}
if (lfscheck(dirptr) == SYSERR ) {
kprintf("Disk does not contain a Xinu file system\n");
signal(Lf_data.lf_mutex);
return SYSERR;
}
Lf_data.lf_dirpresent = TRUE;
}
/* Search directory to see if file exists */
found = FALSE;
for (i=0; i<dirptr->lfd_nfiles; i++) {
ldptr = &dirptr->lfd_files[i];
nam = name;
cmp = ldptr->ld_name;
while(*nam != NULLCH) {
if (*nam != *cmp) {
break;
}
nam++;
cmp++;
}
if ( (*nam==NULLCH) && (*cmp==NULLCH) ) { /* Name found */
found = TRUE;
break;
}
}
/* Case #1 - file is not in directory (i.e., does not exist) */
if (! found) {
if (mbits & LF_MODE_O) { /* File *must* exist */
signal(Lf_data.lf_mutex);
return SYSERR;
}
/* Take steps to create new file and add to directory */
/* Verify that space remains in the directory */
if (dirptr->lfd_nfiles >= LF_NUM_DIR_ENT) {
signal(Lf_data.lf_mutex);
return SYSERR;
}
/* Allocate next dir. entry & initialize to empty file */
ldptr = &dirptr->lfd_files[dirptr->lfd_nfiles++];
ldptr->ld_size = 0;
from = name;
to = ldptr->ld_name;
while ( (*to++ = *from++) != NULLCH ) {
;
}
ldptr->ld_ilist = LF_INULL;
/* Case #2 - file is in directory (i.e., already exists) */
} else if (mbits & LF_MODE_N) { /* File must not exist */
signal(Lf_data.lf_mutex);
return SYSERR;
}
/* Initialize the local file pseudo-device */
lfptr = &lfltab[lfnext];
lfptr->lfstate = LF_USED;
lfptr->lfdirptr = ldptr; /* Point to directory entry */
lfptr->lfmode = mbits & LF_MODE_RW;
/* File starts at position 0 */
lfptr->lfpos = 0;
to = lfptr->lfname;
from = name;
while ( (*to++ = *from++) != NULLCH ) {
;
}
/* Neither index block nor data block are initially valid */
lfptr->lfinum = LF_INULL;
lfptr->lfdnum = LF_DNULL;
/* Initialize byte pointer to address beyond the end of the */
/* buffer (i.e., invalid pointer triggers setup) */
lfptr->lfbyte = &lfptr->lfdblock[LF_BLKSIZ];
lfptr->lfibdirty = FALSE;
lfptr->lfdbdirty = FALSE;
signal(Lf_data.lf_mutex);
return lfptr->lfdev;
}

104
device/lfs/lftruncate.c

@ -0,0 +1,104 @@
/* lftruncate.c - lftruncate */
#include <xinu.h>
/*------------------------------------------------------------------------
* lftruncate - Truncate a file by freeing its index and data blocks
* (assumes directory mutex held)
*------------------------------------------------------------------------
*/
status lftruncate (
struct lflcblk *lfptr /* Ptr to file's cntl blk entry */
)
{
struct ldentry *ldptr; /* Pointer to file's dir. entry */
struct lfiblk iblock; /* Buffer for one index block */
ibid32 ifree; /* Start of index blk free list */
ibid32 firstib; /* First index blk of the file */
ibid32 nextib; /* Walks down list of the */
/* file's index blocks */
dbid32 nextdb; /* Next data block to free */
int32 i; /* Moves through data blocks in */
/* a given index block */
ldptr = lfptr->lfdirptr; /* Get pointer to dir. entry */
if (ldptr->ld_size == 0) { /* File is already empty */
return OK;
}
/* Clean up the open local file first */
if ( (lfptr->lfibdirty) || (lfptr->lfdbdirty) ) {
lfflush(lfptr);
}
lfptr->lfpos = 0;
lfptr->lfinum = LF_INULL;
lfptr->lfdnum = LF_DNULL;
lfptr->lfbyte = &lfptr->lfdblock[LF_BLKSIZ];
/* Obtain ID of first index block on free list */
ifree = Lf_data.lf_dir.lfd_ifree;
/* Record file's first i-block and clear directory entry */
firstib = ldptr->ld_ilist;
ldptr->ld_ilist = LF_INULL;
ldptr->ld_size = 0;
Lf_data.lf_dirdirty = TRUE;
/* Walk along index block list, disposing of each data block */
/* and clearing the corresponding pointer. A note on loop */
/* termination: last pointer is set to ifree below. */
for (nextib=firstib; nextib!=ifree; nextib=iblock.ib_next) {
/* Obtain a copy of current index block from disk */
lfibget(Lf_data.lf_dskdev, nextib, &iblock);
/* Free each data block in the index block */
for (i=0; i<LF_IBLEN; i++) { /* For each d-block */
/* Free the data block */
nextdb = iblock.ib_dba[i];
if (nextdb != LF_DNULL) {
lfdbfree(Lf_data.lf_dskdev, nextdb);
}
/* Clear entry in i-block for this d-block */
iblock.ib_dba[i] = LF_DNULL;
}
/* Clear offset (just to make debugging easier) */
iblock.ib_offset = 0;
/* For the last index block on the list, make it point */
/* to the current free list */
if (iblock.ib_next == LF_INULL) {
iblock.ib_next = ifree;
}
/* Write cleared i-block back to disk */
lfibput(Lf_data.lf_dskdev, nextib, &iblock);
}
/* Last index block on the file list now points to first node */
/* on the current free list. Once we make the free list */
/* point to the first index block on the file list, the */
/* entire set of index blocks will be on the free list */
Lf_data.lf_dir.lfd_ifree = firstib;
/* Indicate that directory has changed and return */
Lf_data.lf_dirdirty = TRUE;
return OK;
}

64
device/movidos/gpio/gpiocontrol.c

@ -0,0 +1,64 @@
/* gpiocontrol.c - gpiocontrol */
#include <xinu.h>
#define OFFSETMODE(x) (x * 4)
#define OFFSETCFG(x) ((x * 4) + 2)
#define OFFSETMODE2(x) ((x - 8) * 4)
#define OFFSETCFG2(x) (((x - 8) * 4) + 2)
static int setmode(struct dentry * devptr, uint32 mode, uint32 pin)
{
struct gpio_csreg * csrptr;
csrptr = (struct gpio_csreg *)(devptr->dvcsr);
if (pin < 8) {
csrptr->crl &= ~(0x3 << OFFSETMODE(pin)); // clear
csrptr->crl |= (mode << OFFSETMODE(pin));
}
else {
csrptr->crh &= ~(0x3 << OFFSETMODE2(pin)); // clear
csrptr->crh |= (mode << OFFSETMODE2(pin));
}
return 0;
}
static int setcnf(struct dentry * devptr, uint32 mode, uint32 pin)
{
struct gpio_csreg * csrptr;
csrptr = (struct gpio_csreg *)(devptr->dvcsr);
if (pin < 8) {
csrptr->crl &= ~(0x3 << OFFSETCFG(pin)); // clear
csrptr->crl |= (mode << OFFSETCFG(pin));
}
else {
csrptr->crh &= ~(0x3 << OFFSETCFG2(pin)); // clear
csrptr->crh |= (mode << OFFSETCFG2(pin));
}
return 0;
}
/*------------------------------------------------------------------------
* gpiocontrol - Control a gpio device pin settings
*------------------------------------------------------------------------
*/
devcall gpiocontrol(struct dentry * devptr, int32 func, int32 mode, int32 pin) {
switch(func) {
case SETMODE:
setmode(devptr, mode, pin);
break;
case SETCFG:
setcnf(devptr, mode, pin);
break;
default:
break;
}
return OK;
}

85
device/movidos/gpio/gpiohandler.c

@ -0,0 +1,85 @@
/* gpiohandler.c - gpiohandler */
#include <xinu.h>
/*------------------------------------------------------------------------
* gpiohandler - Handle an interrupt for a gpio device
*------------------------------------------------------------------------
*/
void gpiohandler(
uint32 xnum /* IRQ number */
)
{
struct gpio_csreg *csrptr; /* GPIO CSR pointer */
gpiointhook gphookfn; /* The inerrupt function */
/* Clear all interrupts */
// if(xnum == GPIO0_INT_A) {
// csrptr = (struct gpio_csreg *)(GPIO0_BASE);
// gphookfn = gpiotab[0].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus0);
// csrptr->irqstatus0 = 0xFFFFFFFF;
// return;
// }
// if(xnum == GPIO0_INT_B) {
// csrptr = (struct gpio_csreg *)(GPIO0_BASE);
// gphookfn = gpiotab[0].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus1);
// csrptr->irqstatus1 = 0xFFFFFFFF;
// return;
// }
//
// if(xnum == GPIO1_INT_A) {
// csrptr = (struct gpio_csreg *)(GPIO1_BASE);
// gphookfn = gpiotab[1].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus0);
// csrptr->irqstatus0 = 0xFFFFFFFF;
// return;
// }
// if(xnum == GPIO1_INT_B) {
// csrptr = (struct gpio_csreg *)(GPIO1_BASE);
// gphookfn = gpiotab[1].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus1);
// csrptr->irqstatus1 = 0xFFFFFFFF;
// return;
// }
//
// if(xnum == GPIO2_INT_A) {
// csrptr = (struct gpio_csreg *)(GPIO2_BASE);
// gphookfn = gpiotab[2].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus0);
// csrptr->irqstatus0 = 0xFFFFFFFF;
// return;
// }
// if(xnum == GPIO2_INT_B) {
// csrptr = (struct gpio_csreg *)(GPIO2_BASE);
// gphookfn = gpiotab[2].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus1);
// csrptr->irqstatus1 = 0xFFFFFFFF;
// return;
// }
//
// if(xnum == GPIO3_INT_A) {
// csrptr = (struct gpio_csreg *)(GPIO3_BASE);
// gphookfn = gpiotab[3].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus0);
// csrptr->irqstatus0 = 0xFFFFFFFF;
// return;
// }
// if(xnum == GPIO3_INT_B) {
// csrptr = (struct gpio_csreg *)(GPIO3_BASE);
// gphookfn = gpiotab[3].gphookfn;
// if(gphookfn != NULL)
// gphookfn(xnum, csrptr->irqstatus1);
// csrptr->irqstatus1 = 0xFFFFFFFF;
// return;
// }
}

42
device/movidos/gpio/gpioinit.c

@ -0,0 +1,42 @@
/* gpioinit.c - gpioinit */
#include <xinu.h>
struct gpiocblk gpiotab[NGPIO];
/*------------------------------------------------------------------------
* gpioinit - Initialize settings for a gpio device
*------------------------------------------------------------------------
*/
devcall gpioinit(
struct dentry *devptr /* Entry in device switch table */
)
{
//struct gpio_csreg * csrptr;
struct clock_csreg * clockptr;
//struct gpiocblk * gpioptr;
//csrptr = (struct gpio_csreg *)(devptr->dvcsr);
clockptr = (struct clock_csreg *)CLOCK_BASE;
//gpioptr = &gpiotab[devptr->dvminor];
/* Enable clock on GPIO */
switch (devptr->dvminor) {
case 0:
clockptr->apb2enr |= (1 << IOPAEN);
break;
case 1:
clockptr->apb2enr |= (1 << IOPBEN);
break;
case 2:
clockptr->apb2enr |= (1 << IOPCEN);
break;
case 3:
clockptr->apb2enr |= (1 << IOPDEN);
break;
default:
kprintf("Failed to recognize GPIO device");
return SYSERR;
}
return OK;
}

27
device/movidos/gpio/gpioread.c

@ -0,0 +1,27 @@
/* gpioread.c - gpioread */
#include <xinu.h>
/*------------------------------------------------------------------------
* gpioread - Read aspecified set of GPIO pins
*------------------------------------------------------------------------
*/
devcall gpioread(
struct dentry *devptr, /* Entry in device switch table */
char *value, /* Pointer to a 32bit buffer */
int32 pinmask /* Pins from which to read */
)
{
// struct gpio_csreg *csrptr; /* Pointer to GPIO CSRs */
//
// /* Obtain the address of the CSR from the device switch table */
//
// csrptr = (struct gpio_csreg *)(devptr->dvcsr);
//
// /* Access the GPIO pins, use the mask to select a subset, and */
// /* store the result in the specified buffer */
//
// *((uint32 *)value) = csrptr->datain & pinmask;
return OK;
}

25
device/movidos/gpio/gpioselect.c

@ -0,0 +1,25 @@
/* gpioselect.h - pin multiplexing and control for the BBB ZCZ package */
#include <xinu.h>
/*------------------------------------------------------------------------
* gpioselect - Configure modes for GPIO pins
*------------------------------------------------------------------------
*/
devcall gpioselect(
uint32 pinreg, /* Pin to be affected */
uint32 pinmode, /* Multiplexed pin function */
uint32 pinsettings /* Settings for the pin */
)
{
// volatile uint32* confreg; /* Pin configuration register */
//
// /* Pick up the pin configuration register address */
//
// confreg = &(((uint32*)PINMUXBASE)[pinreg]);
//
// /* Apply the specified settings to the pin */
//
// *confreg = pinmode|pinsettings;
//
return OK;
}

31
device/movidos/gpio/gpiowrite.c

@ -0,0 +1,31 @@
/* gpiowrite.c - gpiowrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* gpiowrite - Write value of gpio pins
*------------------------------------------------------------------------
*/
devcall gpiowrite(
struct dentry *devptr, /* Entry in device switch table */
char *value, /* Pointer to 32-bit buffer */
int32 pin /* Pins to be written written */
)
{
struct gpio_csreg * csrptr;
uint8 val;
csrptr = (struct gpio_csreg *)(devptr->dvcsr);
val = (uint8)value;
if (val == 0) {
csrptr->odr &= ~(1 << pin);
return 0;
}
else if (val == 1) {
csrptr->odr |= (1 << pin);
return 0;
}
return OK;
}

14
device/movidos/ram/ramclose.c

@ -0,0 +1,14 @@
/* ramclose.c - ramclose */
#include <xinu.h>
/*------------------------------------------------------------------------
* Ramclose - Close a ram disk
*------------------------------------------------------------------------
*/
devcall ramclose (
struct dentry *devptr /* Entry in device switch table */
)
{
return OK;
}

19
device/movidos/ram/raminit.c

@ -0,0 +1,19 @@
/* raminit.c - raminit */
#include <xinu.h>
#include <ramdisk.h>
struct ramdisk Ram;
/*------------------------------------------------------------------------
* raminit - Initialize the remote disk system device
*------------------------------------------------------------------------
*/
devcall raminit (
struct dentry *devptr /* Entry in device switch table */
)
{
memcpy(Ram.disk, "hopeless", 8);
memcpy( &Ram.disk[8], Ram.disk, RM_BLKSIZ * RM_BLKS - 8);
return OK;
}

19
device/movidos/ram/ramopen.c

@ -0,0 +1,19 @@
/* ramopen.c - ramopen */
#include <xinu.h>
/*------------------------------------------------------------------------
* ramopen - Open a ram disk
*------------------------------------------------------------------------
*/
devcall ramopen (
struct dentry *devptr, /* Entry in device switch table */
char *name, /* Unused for a ram disk */
char *mode /* Unused for a ram disk */
)
{
/* No action -- just return the device descriptor */
return devptr->dvnum;
}

21
device/movidos/ram/ramread.c

@ -0,0 +1,21 @@
/* ramread.c - ramread */
#include <xinu.h>
#include <ramdisk.h>
/*------------------------------------------------------------------------
* ramread - Read a block from a ram disk
*------------------------------------------------------------------------
*/
devcall ramread (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer to hold disk block */
int32 blk /* Block number of block to read*/
)
{
int32 bpos; /* Byte position of blk */
bpos = RM_BLKSIZ * blk;
memcpy(buff, &Ram.disk[bpos], RM_BLKSIZ);
return OK;
}

21
device/movidos/ram/ramwrite.c

@ -0,0 +1,21 @@
/* ramwrite.c - ramwrite */
#include <xinu.h>
#include <ramdisk.h>
/*------------------------------------------------------------------------
* ramwrite - Write a block to a ram disk
*------------------------------------------------------------------------
*/
devcall ramwrite (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer containing a block */
int32 blk /* Block number to write */
)
{
int32 bpos; /* Byte position of blk */
bpos = RM_BLKSIZ * blk;
memcpy(&Ram.disk[bpos], buff, RM_BLKSIZ);
return OK;
}

58
device/movidos/tty/ttycontrol.c

@ -0,0 +1,58 @@
/* ttycontrol.c - ttycontrol */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttycontrol - Control a tty device by setting modes
*------------------------------------------------------------------------
*/
devcall ttycontrol(
struct dentry *devptr, /* Entry in device switch table */
int32 func, /* Function to perform */
int32 arg1, /* Argument 1 for request */
int32 arg2 /* Argument 2 for request */
)
{
struct ttycblk *typtr; /* Pointer to tty control block */
char ch; /* Character for lookahead */
typtr = &ttytab[devptr->dvminor];
/* Process the request */
switch ( func ) {
case TC_NEXTC:
wait(typtr->tyisem);
ch = *typtr->tyitail;
signal(typtr->tyisem);
return (devcall)ch;
case TC_MODER:
typtr->tyimode = TY_IMRAW;
return (devcall)OK;
case TC_MODEC:
typtr->tyimode = TY_IMCOOKED;
return (devcall)OK;
case TC_MODEK:
typtr->tyimode = TY_IMCBREAK;
return (devcall)OK;
case TC_ICHARS:
return(semcount(typtr->tyisem));
case TC_ECHO:
typtr->tyiecho = TRUE;
return (devcall)OK;
case TC_NOECHO:
typtr->tyiecho = FALSE;
return (devcall)OK;
default:
return (devcall)SYSERR;
}
}

41
device/movidos/tty/ttygetc.c

@ -0,0 +1,41 @@
/* ttygetc.c - ttygetc */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttygetc - Read one character from a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttygetc(
struct dentry *devptr /* Entry in device switch table */
)
{
char ch; /* Character to return */
struct ttycblk *typtr; /* Pointer to ttytab entry */
typtr = &ttytab[devptr->dvminor];
/* Wait for a character in the buffer and extract one character */
// struct sentry * semptr;
// semptr = &semtab[typtr->tyisem];
// while(--(semptr->scount) < 0);
wait(typtr->tyisem);
ch = *typtr->tyihead++;
/* Wrap around to beginning of buffer, if needed */
if (typtr->tyihead >= &typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyihead = typtr->tyibuff;
}
/* In cooked mode, check for the EOF character */
if ( (typtr->tyimode == TY_IMCOOKED) && (typtr->tyeof) &&
(ch == typtr->tyeofch) ) {
return (devcall)EOF;
}
return (devcall)ch;
}

267
device/movidos/tty/ttyhandle_in.c

@ -0,0 +1,267 @@
/* ttyhandle_in.c - ttyhandle_in, erase1, eputc, echoch */
#include <xinu.h>
local void erase1(struct ttycblk *, struct uart_csreg *);
local void echoch(char, struct ttycblk *, struct uart_csreg *);
local void eputc(char, struct ttycblk *, struct uart_csreg *);
/*------------------------------------------------------------------------
* ttyhandle_in - Handle one arriving char (interrupts disabled)
*------------------------------------------------------------------------
*/
void ttyhandle_in (
struct ttycblk *typtr, /* Pointer to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSR */
)
{
char ch; /* Next char from device */
int32 avail; /* Chars available in buffer */
ch = csrptr->dr;
/* Compute chars available */
avail = semcount(typtr->tyisem);
if (avail < 0) { /* One or more processes waiting*/
avail = 0;
}
/* Handle raw mode */
if (typtr->tyimode == TY_IMRAW) {
if (avail >= TY_IBUFLEN) { /* No space => ignore input */
return;
}
/* Place char in buffer with no editing */
*typtr->tyitail++ = ch;
/* Wrap buffer pointer */
if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
/* Signal input semaphore and return */
signal(typtr->tyisem);
return;
}
/* Handle cooked and cbreak modes (common part) */
if ( (ch == TY_RETURN) && typtr->tyicrlf ) {
ch = TY_NEWLINE;
}
/* If flow control is in effect, handle ^S and ^Q */
if (typtr->tyoflow) {
if (ch == typtr->tyostart) { /* ^Q starts output */
typtr->tyoheld = FALSE;
ttykickout(csrptr);
return;
} else if (ch == typtr->tyostop) { /* ^S stops output */
typtr->tyoheld = TRUE;
return;
}
}
typtr->tyoheld = FALSE; /* Any other char starts output */
if (typtr->tyimode == TY_IMCBREAK) { /* Just cbreak mode */
/* If input buffer is full, send bell to user */
if (avail >= TY_IBUFLEN) {
eputc(typtr->tyifullc, typtr, csrptr);
} else { /* Input buffer has space for this char */
*typtr->tyitail++ = ch;
/* Wrap around buffer */
if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
if (typtr->tyiecho) { /* Are we echoing chars?*/
echoch(ch, typtr, csrptr);
}
signal(typtr->tyisem);
}
return;
} else { /* Just cooked mode (see common code above) */
/* Line kill character arrives - kill entire line */
if (ch == typtr->tyikillc && typtr->tyikill) {
typtr->tyitail -= typtr->tyicursor;
if (typtr->tyitail < typtr->tyibuff) {
typtr->tyitail += TY_IBUFLEN;
}
typtr->tyicursor = 0;
eputc(TY_RETURN, typtr, csrptr);
eputc(TY_NEWLINE, typtr, csrptr);
return;
}
/* Erase (backspace) character */
if ( ((ch==typtr->tyierasec) || (ch==typtr->tyierasec2))
&& typtr->tyierase) {
if (typtr->tyicursor > 0) {
typtr->tyicursor--;
erase1(typtr, csrptr);
}
return;
}
/* End of line */
if ( (ch == TY_NEWLINE) || (ch == TY_RETURN) ) {
if (typtr->tyiecho) {
echoch(ch, typtr, csrptr);
}
*typtr->tyitail++ = ch;
if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
/* Make entire line (plus \n or \r) available */
signaln(typtr->tyisem, typtr->tyicursor + 1);
typtr->tyicursor = 0; /* Reset for next line */
return;
}
/* Character to be placed in buffer - send bell if */
/* buffer has overflowed */
avail = semcount(typtr->tyisem);
if (avail < 0) {
avail = 0;
}
if ((avail + typtr->tyicursor) >= TY_IBUFLEN-1) {
eputc(typtr->tyifullc, typtr, csrptr);
return;
}
/* EOF character: recognize at beginning of line, but */
/* print and ignore otherwise. */
if (ch == typtr->tyeofch && typtr->tyeof) {
if (typtr->tyiecho) {
echoch(ch, typtr, csrptr);
}
if (typtr->tyicursor != 0) {
return;
}
*typtr->tyitail++ = ch;
signal(typtr->tyisem);
return;
}
/* Echo the character */
if (typtr->tyiecho) {
echoch(ch, typtr, csrptr);
}
/* Insert in the input buffer */
typtr->tyicursor++;
*typtr->tyitail++ = ch;
/* Wrap around if needed */
if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
return;
}
}
/*------------------------------------------------------------------------
* erase1 - Erase one character honoring erasing backspace
*------------------------------------------------------------------------
*/
local void erase1(
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
char ch; /* Character to erase */
if ( (--typtr->tyitail) < typtr->tyibuff) {
typtr->tyitail += TY_IBUFLEN;
}
/* Pick up char to erase */
ch = *typtr->tyitail;
if (typtr->tyiecho) { /* Are we echoing? */
if (ch < TY_BLANK || ch == 0177) { /* Nonprintable */
if (typtr->tyevis) { /* Visual cntl chars */
eputc(TY_BACKSP, typtr, csrptr);
if (typtr->tyieback) { /* Erase char */
eputc(TY_BLANK, typtr, csrptr);
eputc(TY_BACKSP, typtr, csrptr);
}
}
eputc(TY_BACKSP, typtr, csrptr);/* Bypass up arr*/
if (typtr->tyieback) {
eputc(TY_BLANK, typtr, csrptr);
eputc(TY_BACKSP, typtr, csrptr);
}
} else { /* A normal character that is printable */
eputc(TY_BACKSP, typtr, csrptr);
if (typtr->tyieback) { /* erase the character */
eputc(TY_BLANK, typtr, csrptr);
eputc(TY_BACKSP, typtr, csrptr);
}
}
}
return;
}
/*------------------------------------------------------------------------
* echoch - Echo a character with visual and output crlf options
*------------------------------------------------------------------------
*/
local void echoch(
char ch, /* Character to echo */
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
if ((ch==TY_NEWLINE || ch==TY_RETURN) && typtr->tyecrlf) {
eputc(TY_RETURN, typtr, csrptr);
eputc(TY_NEWLINE, typtr, csrptr);
} else if ( (ch<TY_BLANK||ch==0177) && typtr->tyevis) {
eputc(TY_UPARROW, typtr, csrptr);/* print ^x */
eputc(ch+0100, typtr, csrptr); /* Make it printable */
} else {
eputc(ch, typtr, csrptr);
}
}
/*------------------------------------------------------------------------
* eputc - Put one character in the echo queue
*------------------------------------------------------------------------
*/
local void eputc(
char ch, /* Character to echo */
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
*typtr->tyetail++ = ch;
/* Wrap around buffer, if needed */
if (typtr->tyetail >= &typtr->tyebuff[TY_EBUFLEN]) {
typtr->tyetail = typtr->tyebuff;
}
ttykickout(csrptr);
return;
}

83
device/movidos/tty/ttyhandle_out.c

@ -0,0 +1,83 @@
/* ttyhandle_out.c - ttyhandle_out */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyhandle_out - Handle an output on a tty device by sending more
* characters to the device FIFO (interrupts disabled)
*------------------------------------------------------------------------
*/
void ttyhandle_out(
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
int32 ochars; /* Number of output chars sent */
/* to the UART */
int32 avail; /* Available chars in output buf*/
int32 uspace; /* Space left in onboard UART */
/* output FIFO */
//uint32 ier = 0;
/* If output is currently held, simply ignore the call */
if (typtr->tyoheld) {
return;
}
/* If echo and output queues empty, turn off interrupts */
if ( (typtr->tyehead == typtr->tyetail) &&
(semcount(typtr->tyosem) >= TY_OBUFLEN) ) {
csrptr->cr1 &= ~(1 << UART_INTR_TX);
//ier = csrptr->ier;
//csrptr->ier = ier & ~UART_IER_ETBEI;
return;
}
/* Initialize uspace to the available space in the Tx FIFO */
//uspace = UART_FIFO_SIZE - csrptr->txfifo_lvl;
uspace = UART_FIFO_SIZE;
/* While onboard FIFO is not full and the echo queue is */
/* nonempty, xmit chars from the echo queue */
while ( (uspace>0) && typtr->tyehead != typtr->tyetail) {
csrptr->dr = *typtr->tyehead++;
if (typtr->tyehead >= &typtr->tyebuff[TY_EBUFLEN]) {
typtr->tyehead = typtr->tyebuff;
}
uspace--;
}
/* While onboard FIFO is not full and the output queue is */
/* nonempty, transmit chars from the output queue */
ochars = 0;
avail = TY_OBUFLEN - semcount(typtr->tyosem);
while ( (uspace>0) && (avail > 0) ) {
//while(!(csrptr->sr & UART_TC));
//while(csrptr->sr &= ~(1 << UART_TEST));
csrptr->dr = *typtr->tyohead++;
if (typtr->tyohead >= &typtr->tyobuff[TY_OBUFLEN]) {
typtr->tyohead = typtr->tyobuff;
}
avail--;
uspace--;
ochars++;
}
if (ochars > 0) {
signaln(typtr->tyosem, ochars);
}
if ( (typtr->tyehead == typtr->tyetail) &&
(semcount(typtr->tyosem) >= TY_OBUFLEN) ) {
csrptr->cr1 &= ~(1 << UART_INTR_TX);
//ier = csrptr->ier;
//csrptr->ier = (ier & ~UART_IER_ETBEI);
}
return;
}

114
device/movidos/tty/ttyhandler.c

@ -0,0 +1,114 @@
/* ttyhandler.c - ttyhandler */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyhandler - Handle an interrupt for a tty (serial) device
*------------------------------------------------------------------------
*/
void ttyhandler(uint32 xnum) {
struct dentry *devptr; /* Address of device control blk*/
struct ttycblk *typtr; /* Pointer to ttytab entry */
struct uart_csreg *csrptr; /* Address of UART's CSR */
// uint32 iir = 0; /* Interrupt identification */
// uint32 lsr = 0; /* Line status */
//
//
/* Get CSR address of the device (assume console for now) */
devptr = (struct dentry *) &devtab[CONSOLE];
csrptr = (struct uart_csreg *) devptr->dvcsr;
/* Obtain a pointer to the tty control block */
typtr = &ttytab[devptr->dvminor];
/* Test type of UART interrupt */
uint8 flags = csrptr->sr & 0xFF;
//kprintf("%x", flags);
if (flags & UART_RXNE) {
ttyhandle_in(typtr, csrptr);
return;
}
else if (flags & UART_TC) {
ttyhandle_out(typtr, csrptr);
return;
}
// switch(flags) {
//
// case UART_TC_TXE:
// case UART_TC:
// ttyhandle_out(typtr, csrptr);
// return;
// case UART_RXNE:
// ttyhandle_in(typtr, csrptr);
// return;
//
// default:
// kprintf("Unknown status\n");
// return;
// }
// /* Decode hardware interrupt request from UART device */
//
// /* Check interrupt identification register */
// iir = csrptr->iir;
// if (iir & UART_IIR_IRQ) {
// return;
// }
//
// /* Decode the interrupt cause based upon the value extracted */
// /* from the UART interrupt identification register. Clear */
// /* the interrupt source and perform the appropriate handling */
// /* to coordinate with the upper half of the driver */
//
// /* Decode the interrupt cause */
//
// iir &= UART_IIR_IDMASK; /* Mask off the interrupt ID */
// switch (iir) {
//
// /* Receiver line status interrupt (error) */
//
// case UART_IIR_RLSI:
// lsr = csrptr->lsr;
// if(lsr & UART_LSR_BI) { /* Break Interrupt */
//
// /* Read the RHR register to acknowledge */
//
// lsr = csrptr->buffer;
// }
// return;
//
// /* Receiver data available or timed out */
//
// case UART_IIR_RDA:
// case UART_IIR_RTO:
//
// resched_cntl(DEFER_START);
//
// /* While chars avail. in UART buffer, call ttyhandle_in */
//
// while ( (csrptr->lsr & UART_LSR_DR) != 0) {
// ttyhandle_in(typtr, csrptr);
// }
//
// resched_cntl(DEFER_STOP);
//
// return;
//
// /* Transmitter output FIFO is empty (i.e., ready for more) */
//
// case UART_IIR_THRE:
// ttyhandle_out(typtr, csrptr);
// return;
//
// /* Modem status change (simply ignore) */
//
// case UART_IIR_MSC:
// return;
// }
}

83
device/movidos/tty/ttyinit.c

@ -0,0 +1,83 @@
/* ttyinit.c - ttyinit */
#include <xinu.h>
struct ttycblk ttytab[Ntty];
/*------------------------------------------------------------------------
* ttyinit - Initialize buffers and modes for a tty line
*------------------------------------------------------------------------
*/
devcall ttyinit(
struct dentry *devptr /* Entry in device switch table */
)
{
struct ttycblk *typtr; /* Pointer to ttytab entry */
struct uart_csreg *uptr; /* Address of UART's CSRs */
typtr = &ttytab[ devptr->dvminor ];
/* Initialize values in the tty control block */
typtr->tyihead = typtr->tyitail = /* Set up input queue */
&typtr->tyibuff[0]; /* as empty */
typtr->tyisem = semcreate(0); /* Input semaphore */
typtr->tyohead = typtr->tyotail = /* Set up output queue */
&typtr->tyobuff[0]; /* as empty */
typtr->tyosem = semcreate(TY_OBUFLEN); /* Output semaphore */
typtr->tyehead = typtr->tyetail = /* Set up echo queue */
&typtr->tyebuff[0]; /* as empty */
typtr->tyimode = TY_IMCOOKED; /* Start in cooked mode */
typtr->tyiecho = TRUE; /* Echo console input */
typtr->tyieback = TRUE; /* Honor erasing bksp */
typtr->tyevis = TRUE; /* Visual control chars */
typtr->tyecrlf = TRUE; /* Echo CRLF for NEWLINE*/
typtr->tyicrlf = TRUE; /* Map CR to NEWLINE */
typtr->tyierase = TRUE; /* Do erasing backspace */
typtr->tyierasec = TY_BACKSP; /* Primary erase char */
typtr->tyierasec2= TY_BACKSP2; /* Alternate erase char */
typtr->tyeof = TRUE; /* Honor eof on input */
typtr->tyeofch = TY_EOFCH; /* End-of-file character*/
typtr->tyikill = TRUE; /* Allow line kill */
typtr->tyikillc = TY_KILLCH; /* Set line kill to ^U */
typtr->tyicursor = 0; /* Start of input line */
typtr->tyoflow = TRUE; /* Handle flow control */
typtr->tyoheld = FALSE; /* Output not held */
typtr->tyostop = TY_STOPCH; /* Stop char is ^S */
typtr->tyostart = TY_STRTCH; /* Start char is ^Q */
typtr->tyocrlf = TRUE; /* Send CRLF for NEWLINE*/
typtr->tyifullc = TY_FULLCH; /* Send ^G when buffer */
/* is full */
/* Initialize UART */
struct gpio_csreg *gptr;
struct clock_csreg *cptr;
/* Enable 'clock' on peripherals */
cptr = (struct clock_csreg *)CLOCK_BASE;
cptr->apb2enr |= (1 << IOPAEN) | (1 << USART1EN);
/* Set in and output mode */
gptr = (struct gpio_csreg *)(0x40010800);
gptr->crh = 0x44444894;
/* Enable peripheral */
uptr = (struct uart_csreg *)(0x40013800);
uptr->cr1 &= ~(1 << UART_EN);
/* Set baudrate 115200 */
uptr->brr = 0x00000045;
uptr->cr1 |= (1 << UART_TX_EN) | (1 << UART_RX_EN); /* Enable lines */
uptr->cr1 |= (1 << UART_INTR_RX) | (1 << UART_INTR_TX); /* Enable interrupts */
/* Set and enable interrupt vector */
set_evec(devptr->dvirq, (uint32)devptr->dvintr);
*NVIC_ISER1 |= (1 << 5);
/* Start the device */
uptr->cr1 |= (1 << UART_EN);
// ttykickout(uptr);
return OK;
}

19
device/movidos/tty/ttykickout.c

@ -0,0 +1,19 @@
/* ttykickout.c - ttykickout */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttykickout - "Kick" the hardware for a tty device, causing it to
* generate an output interrupt (interrupts disabled)
*------------------------------------------------------------------------
*/
void ttykickout(
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
/* Force the UART hardware generate an output interrupt */
csrptr->cr1 |= (1 << UART_INTR_TX);
*NVIC_STIR = 0x25; /* Generate general UART interrupt */
return;
}

44
device/movidos/tty/ttyputc.c

@ -0,0 +1,44 @@
/* ttyputc.c - ttyputc */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyputc - Write one character to a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttyputc(
struct dentry *devptr, /* Entry in device switch table */
char ch /* Character to write */
)
{
//struct uart_csreg * uptr;
struct ttycblk *typtr; /* Pointer to tty control block */
//uptr = (struct uart_csreg *)devptr->csreg;
typtr = &ttytab[devptr->dvminor];
/* Handle output CRLF by sending CR first */
if ( ch==TY_NEWLINE && typtr->tyocrlf ) {
ttyputc(devptr, TY_RETURN);
}
wait(typtr->tyosem); /* Wait for space in queue */
*typtr->tyotail++ = ch;
/* Wrap around to beginning of buffer, if needed */
if (typtr->tyotail >= &typtr->tyobuff[TY_OBUFLEN]) {
typtr->tyotail = typtr->tyobuff;
}
/* Start output in case device is idle */
//while () {
//
// uptr->dr =
//}
ttykickout((struct uart_csreg *)devptr->dvcsr);
return OK;
}

68
device/movidos/tty/ttyread.c

@ -0,0 +1,68 @@
/* ttyread.c - ttyread */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyread - Read character(s) from a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttyread(
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer of characters */
int32 count /* Count of character to read */
)
{
struct ttycblk *typtr; /* Pointer to tty control block */
int32 avail; /* Characters available in buff.*/
int32 nread; /* Number of characters read */
int32 firstch; /* First input character on line*/
char ch; /* Next input character */
if (count < 0) {
return SYSERR;
}
typtr= &ttytab[devptr->dvminor];
if (typtr->tyimode != TY_IMCOOKED) {
/* For count of zero, return all available characters */
if (count == 0) {
avail = semcount(typtr->tyisem);
if (avail == 0) {
return 0;
} else {
count = avail;
}
}
for (nread = 0; nread < count; nread++) {
*buff++ = (char) ttygetc(devptr);
}
return nread;
}
/* Block until input arrives */
firstch = ttygetc(devptr);
/* Check for End-Of-File */
if (firstch == EOF) {
return EOF;
}
/* Read up to a line */
ch = (char) firstch;
*buff++ = ch;
nread = 1;
while ( (nread < count) && (ch != TY_NEWLINE) &&
(ch != TY_RETURN) ) {
ch = ttygetc(devptr);
*buff++ = ch;
nread++;
}
return nread;
return OK;
}

29
device/movidos/tty/ttywrite.c

@ -0,0 +1,29 @@
/* ttywrite.c - ttywrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttywrite - Write character(s) to a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttywrite(
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer of characters */
int32 count /* Count of character to write */
)
{
/* Handle negative and zero counts */
if (count < 0) {
return SYSERR;
} else if (count == 0){
return OK;
}
/* Write count characters one at a time */
for (; count>0 ; count--) {
ttyputc(devptr, *buff++);
}
return OK;
}

76
device/nam/mount.c

@ -0,0 +1,76 @@
/* mount.c - mount, namlen */
#include <xinu.h>
/*------------------------------------------------------------------------
* mount - Add a prefix mapping to the name space
*------------------------------------------------------------------------
*/
syscall mount(
char *prefix, /* Prefix to add */
char *replace, /* Replacement string */
did32 device /* Device ID to use */
)
{
intmask mask; /* Saved interrupt mask */
struct nmentry *namptr; /* Pointer to unused table entry*/
int32 psiz, rsiz; /* Sizes of prefix & replacement*/
int32 i; /* Counter for copy loop */
mask = disable();
psiz = namlen(prefix, NM_PRELEN);
rsiz = namlen(replace, NM_REPLLEN);
/* If arguments are invalid or table is full, return error */
if ( (psiz == SYSERR) || (rsiz == SYSERR) ||
(isbaddev(device)) || (nnames >= NNAMES) ) {
restore(mask);
return SYSERR;
}
/* Allocate a slot in the table */
namptr = &nametab[nnames]; /* Next unused entry in table */
/* copy prefix and replacement strings and record device ID */
for (i=0; i<psiz; i++) { /* Copy prefix into table entry */
namptr->nprefix[i] = *prefix++;
}
for (i=0; i<rsiz; i++) { /* Copy replacement into entry */
namptr->nreplace[i] = *replace++;
}
namptr->ndevice = device; /* Record the device ID */
nnames++; /* Increment number of names */
restore(mask);
return OK;
}
/*------------------------------------------------------------------------
* namlen - Compute the length of a string stopping at maxlen
*------------------------------------------------------------------------
*/
int32 namlen(
char *name, /* Name to use */
int32 maxlen /* Maximum length (including a */
/* NULLCH) */
)
{
int32 i; /* Count of characters found */
/* Search until a null terminator or length reaches max */
for (i=0; i < maxlen; i++) {
if (*name++ == NULLCH) {
return i+1; /* Include NULLCH in length */
}
}
return SYSERR;
}

93
device/nam/naminit.c

@ -0,0 +1,93 @@
/* naminit.c - naminit */
#include <xinu.h>
#ifndef RFILESYS
#define RFILESYS SYSERR
#endif
#ifndef FILESYS
#define FILESYS SYSERR
#endif
#ifndef LFILESYS
#define LFILESYS SYSERR
#endif
struct nmentry nametab[NNAMES]; /* Table of name mappings */
int32 nnames; /* Number of entries allocated */
/*------------------------------------------------------------------------
* naminit - Initialize the syntactic namespace
*------------------------------------------------------------------------
*/
status naminit(void)
{
did32 i; /* Index into devtab */
struct dentry *devptr; /* Pointer to device table entry*/
char tmpstr[NM_MAXLEN]; /* String to hold a name */
status retval; /* Return value */
char *tptr; /* Pointer into tempstring */
char *nptr; /* Pointer to device name */
char devprefix[] = "/dev/"; /* Prefix to use for devices */
int32 len; /* Length of created name */
char ch; /* Storage for a character */
/* Set prefix table to empty */
nnames = 0;
for (i=0; i<NDEVS ; i++) {
tptr = tmpstr;
nptr = devprefix;
/* Copy prefix into tmpstr */
len = 0;
while ((*tptr++ = *nptr++) != NULLCH) {
len++;
}
tptr--; /* Move pointer to position before NULLCH */
devptr = &devtab[i];
nptr = devptr->dvname; /* Move to device name */
/* Map device name to lower case and append */
while(++len < NM_MAXLEN) {
ch = *nptr++;
if ( (ch >= 'A') && (ch <= 'Z')) {
ch += 'a' - 'A';
}
if ( (*tptr++ = ch) == NULLCH) {
break;
}
}
if (len > NM_MAXLEN) {
// RAFA kprintf("namespace: device name %s too long\r\n",
kprintf(&m5[0],
devptr->dvname);
continue;
}
retval = mount(tmpstr, NULLSTR, devptr->dvnum);
if (retval == SYSERR) {
// RAFA kprintf("namespace: cannot mount device %d\r\n",
kprintf(&m4[0],
devptr->dvname);
continue;
}
}
/* Add other prefixes (longest prefix first) */
mount("/dev/null", "", NULLDEV);
// mount("/remote/", "remote:", RFILESYS);
// mount("/local/", NULLSTR, LFILESYS);
mount("/dev/", NULLSTR, SYSERR);
// mount("~/", NULLSTR, LFILESYS);
// mount("/", "root:", RFILESYS);
// mount("", "", LFILESYS);
return OK;
}

135
device/nam/nammap.c

@ -0,0 +1,135 @@
/* nammap.c - nammap, namrepl, namcpy */
#include <xinu.h>
status namcpy(char *, char *, int32);
did32 namrepl(char *, char[]);
/*------------------------------------------------------------------------
* nammap - Using namespace, map name to new name and new device
*------------------------------------------------------------------------
*/
devcall nammap(
char *name, /* The name to map */
char newname[NM_MAXLEN], /* Buffer for mapped name */
did32 namdev /* ID of the namespace device */
)
{
did32 newdev; /* Device descriptor to return */
char tmpname[NM_MAXLEN]; /* Temporary buffer for name */
int32 iter; /* Number of iterations */
/* Place original name in temporary buffer and null terminate */
if (namcpy(tmpname, name, NM_MAXLEN) == SYSERR) {
return SYSERR;
}
/* Repeatedly substitute the name prefix until a non-namespace */
/* device is reached or an iteration limit is exceeded */
for (iter=0; iter<nnames ; iter++) {
newdev = namrepl(tmpname, newname);
if (newdev != namdev) {
return newdev; /* Either valid ID or SYSERR */
}
namcpy(tmpname, newname, NM_MAXLEN);
}
return SYSERR;
}
/*------------------------------------------------------------------------
* namrepl - Use the name table to perform prefix substitution
*------------------------------------------------------------------------
*/
did32 namrepl(
char *name, /* Original name */
char newname[NM_MAXLEN] /* Buffer for mapped name */
)
{
int32 i; /* Iterate through name table */
char *pptr; /* Walks through a prefix */
char *rptr; /* Walks through a replacement */
char *optr; /* Walks through original name */
char *nptr; /* Walks through new name */
char olen; /* Length of original name */
/* including the NULL byte */
int32 plen; /* Length of a prefix string */
/* *not* including NULL byte */
int32 rlen; /* Length of replacment string */
int32 remain; /* Bytes in name beyond prefix */
struct nmentry *namptr; /* Pointer to a table entry */
/* Search name table for first prefix that matches */
for (i=0; i<nnames; i++) {
namptr = &nametab[i];
optr = name; /* Start at beginning of name */
pptr = namptr->nprefix; /* Start at beginning of prefix */
/* Compare prefix to string and count prefix size */
for (plen=0; *pptr != NULLCH ; plen++) {
if (*pptr != *optr) {
break;
}
pptr++;
optr++;
}
if (*pptr != NULLCH) { /* Prefix does not match */
continue;
}
/* Found a match - check that replacement string plus */
/* bytes remaining at the end of the original name will */
/* fit into new name buffer. Ignore null on replacement*/
/* string, but keep null on remainder of name. */
olen = namlen(name ,NM_MAXLEN);
rlen = namlen(namptr->nreplace,NM_MAXLEN) - 1;
remain = olen - plen;
if ( (rlen + remain) > NM_MAXLEN) {
return (did32)SYSERR;
}
/* Place replacement string followed by remainder of */
/* original name (and null) into the new name buffer */
nptr = newname;
rptr = namptr->nreplace;
for (; rlen>0 ; rlen--) {
*nptr++ = *rptr++;
}
for (; remain>0 ; remain--) {
*nptr++ = *optr++;
}
return namptr->ndevice;
}
return (did32)SYSERR;
}
/*------------------------------------------------------------------------
* namcpy - Copy a name from one buffer to another, checking length
*------------------------------------------------------------------------
*/
status namcpy(
char *newname, /* Buffer to hold copy */
char *oldname, /* Buffer containing name */
int32 buflen /* Size of buffer for copy */
)
{
char *nptr; /* Point to new name */
char *optr; /* Point to old name */
int32 cnt; /* Count of characters copied */
nptr = newname;
optr = oldname;
for (cnt=0; cnt<buflen; cnt++) {
if ( (*nptr++ = *optr++) == NULLCH) {
return OK;
}
}
return SYSERR; /* Buffer filled before copy completed */
}

29
device/nam/namopen.c

@ -0,0 +1,29 @@
/* namopen.c - namopen */
#include <xinu.h>
/*------------------------------------------------------------------------
* namopen - Open a file or device based on the name
*------------------------------------------------------------------------
*/
devcall namopen(
struct dentry *devptr, /* Entry in device switch table */
char *name, /* Name to open */
char *mode /* Mode argument */
)
{
char newname[NM_MAXLEN]; /* Name with prefix replaced */
did32 newdev; /* Device ID after mapping */
/* Use namespace to map name to a new name and new descriptor */
newdev = nammap(name, newname, devptr->dvnum);
if (newdev == SYSERR) {
return SYSERR;
}
/* Open underlying device and return status */
return open(newdev, newname, mode);
}

50
device/rds/rdsbufalloc.c

@ -0,0 +1,50 @@
/* rdsbufalloc.c - rdsbufalloc */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdsbufalloc - Allocate a buffer from the free list or the cache
*------------------------------------------------------------------------
*/
struct rdbuff *rdsbufalloc (
struct rdscblk *rdptr /* Ptr to device control block */
)
{
struct rdbuff *bptr; /* Pointer to a buffer */
struct rdbuff *pptr; /* Pointer to previous buffer */
struct rdbuff *nptr; /* Pointer to next buffer */
/* Wait for an available buffer */
wait(rdptr->rd_availsem);
/* If free list contains a buffer, extract it */
bptr = rdptr->rd_free;
if ( bptr != (struct rdbuff *)NULL ) {
rdptr->rd_free = bptr->rd_next;
return bptr;
}
/* Extract oldest item in cache that has ref count zero (at */
/* least one such entry must exist because the semaphore */
/* had a nonzero count) */
bptr = rdptr->rd_ctprev;
while (bptr != (struct rdbuff *) &rdptr->rd_chnext) {
if (bptr->rd_refcnt <= 0) {
/* Remove from cache and return to caller */
pptr = bptr->rd_prev;
nptr = bptr->rd_next;
pptr->rd_next = nptr;
nptr->rd_prev = pptr;
return bptr;
}
bptr = bptr->rd_prev;
}
panic("Remote disk cannot find an available buffer");
return (struct rdbuff *)SYSERR;
}

60
device/rds/rdsclose.c

@ -0,0 +1,60 @@
/* rdsclose.c - rdsclose */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdsclose - Close a remote disk device
*------------------------------------------------------------------------
*/
devcall rdsclose (
struct dentry *devptr /* Entry in device switch table */
)
{
struct rdscblk *rdptr; /* Ptr to control block entry */
struct rdbuff *bptr; /* Ptr to buffer on a list */
struct rdbuff *nptr; /* Ptr to next buff on the list */
int32 nmoved; /* Number of buffers moved */
/* Device must be open */
rdptr = &rdstab[devptr->dvminor];
if (rdptr->rd_state != RD_OPEN) {
return SYSERR;
}
/* Request queue must be empty */
if (rdptr->rd_rhnext != (struct rdbuff *)&rdptr->rd_rtnext) {
return SYSERR;
}
/* Move all buffers from the cache to the free list */
bptr = rdptr->rd_chnext;
nmoved = 0;
while (bptr != (struct rdbuff *)&rdptr->rd_ctnext) {
nmoved++;
/* Unlink buffer from cache */
nptr = bptr->rd_next;
(bptr->rd_prev)->rd_next = nptr;
nptr->rd_prev = bptr->rd_prev;
/* Insert buffer into free list */
bptr->rd_next = rdptr->rd_free;
rdptr->rd_free = bptr;
bptr->rd_status = RD_INVALID;
/* Move to next buffer in the cache */
bptr = nptr;
}
/* Set the state to indicate the device is closed */
rdptr->rd_state = RD_FREE;
return OK;
}

124
device/rds/rdscomm.c

@ -0,0 +1,124 @@
/* rdscomm.c - rdscomm */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdscomm - handle communication with a remote disk server (send a
* request and receive a reply, including sequencing and
* retries)
*------------------------------------------------------------------------
*/
status rdscomm (
struct rd_msg_hdr *msg, /* Message to send */
int32 mlen, /* Message length */
struct rd_msg_hdr *reply, /* Buffer for reply */
int32 rlen, /* Size of reply buffer */
struct rdscblk *rdptr /* Ptr to device control block */
)
{
intmask mask; /* Saved interrupt mask */
int32 i; /* Counts retries */
int32 retval; /* Return value */
int32 seq; /* Sequence for this exchange */
uint32 localip; /* Local IP address */
int16 rtype; /* Reply type in host byte order*/
bool8 xmit; /* Should we transmit again? */
int32 slot; /* UDP slot */
/* Disable interrupts while testing status */
mask = disable();
/* Register the server port, if not registered */
if ( ! rdptr->rd_registered ) {
slot = udp_register(0, rdptr->rd_ser_port,
rdptr->rd_loc_port);
if(slot == SYSERR) {
restore(mask);
return SYSERR;
}
rdptr->rd_udpslot = slot;
rdptr->rd_registered = TRUE;
}
/* Get the local IP address */
if ( NetData.ipvalid == FALSE ) {
localip = getlocalip();
if((int32)localip == SYSERR) {
restore(mask);
return SYSERR;
}
}
restore(mask);
/* Retrieve the saved UDP slot number */
slot = rdptr->rd_udpslot;
/* Assign message next sequence number */
seq = rdptr->rd_seq++;
msg->rd_seq = htonl(seq);
/* Repeat RD_RETRIES times: send message and receive reply */
xmit = TRUE;
for (i=0; i<RD_RETRIES; i++) {
if (xmit) {
/* Send a copy of the message */
retval = udp_sendto(slot, rdptr->rd_ser_ip, rdptr->rd_ser_port,
(char *)msg, mlen);
if (retval == SYSERR) {
kprintf("Cannot send to remote disk server\n\r");
return SYSERR;
}
} else {
xmit = TRUE;
}
/* Receive a reply */
retval = udp_recv(slot, (char *)reply, rlen,
RD_TIMEOUT);
if (retval == TIMEOUT) {
continue;
} else if (retval == SYSERR) {
kprintf("Error reading remote disk reply\n\r");
return SYSERR;
}
/* Verify that sequence in reply matches request */
if (ntohl(reply->rd_seq) < seq) {
xmit = FALSE;
} else if (ntohl(reply->rd_seq) != seq) {
continue;
}
/* Verify the type in the reply matches the request */
rtype = ntohs(reply->rd_type);
if (rtype != ( ntohs(msg->rd_type) | RD_MSG_RESPONSE) ) {
continue;
}
/* Check the status */
if (ntohs(reply->rd_status) != 0) {
return SYSERR;
}
return OK;
}
/* Retries exhausted without success */
kprintf("Timeout on exchange with remote disk server\n\r");
return TIMEOUT;
}

131
device/rds/rdscontrol.c

@ -0,0 +1,131 @@
/* rdscontrol.c - rdscontrol */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdscontrol - Provide control functions for the remote disk
*------------------------------------------------------------------------
*/
devcall rdscontrol (
struct dentry *devptr, /* Entry in device switch table */
int32 func, /* The control function to use */
int32 arg1, /* Argument #1 */
int32 arg2 /* Argument #2 */
)
{
struct rdscblk *rdptr; /* Pointer to control block */
struct rdbuff *bptr; /* Ptr to buffer that will be */
/* placed on the req. queue */
struct rdbuff *pptr; /* Ptr to "previous" node on */
/* a list */
struct rd_msg_dreq msg; /* Buffer for delete request */
struct rd_msg_dres resp; /* Buffer for delete response */
char *to, *from; /* Used during name copy */
int32 retval; /* Return value */
/* Verify that device is currently open */
rdptr = &rdstab[devptr->dvminor];
if (rdptr->rd_state != RD_OPEN) {
return SYSERR;
}
/* Ensure rdsprocess is runnning */
if ( ! rdptr->rd_comruns ) {
rdptr->rd_comruns = TRUE;
resume(rdptr->rd_comproc);
}
switch (func) {
/* Synchronize writes */
case RDS_CTL_SYNC:
/* Allocate a buffer to use for the request list */
bptr = rdsbufalloc(rdptr);
if (bptr == (struct rdbuff *)SYSERR) {
return SYSERR;
}
/* Form a sync request */
bptr->rd_op = RD_OP_SYNC;
bptr->rd_refcnt = 1;
bptr->rd_blknum = 0; /* Unused */
bptr->rd_status = RD_INVALID;
bptr->rd_pid = getpid();
/* Insert new request into list just before tail */
pptr = rdptr->rd_rtprev;
rdptr->rd_rtprev = bptr;
bptr->rd_next = pptr->rd_next;
bptr->rd_prev = pptr;
pptr->rd_next = bptr;
/* Prepare to wait until item is processed */
recvclr();
/* Signal then semaphore to start communication */
signal(rdptr->rd_reqsem);
/* Block to wait for a message */
bptr = (struct rdbuff *)receive();
if (bptr == (struct rdbuff *)SYSERR) {
return SYSERR;
}
break;
/* Delete the remote disk (entirely remove it) */
case RDS_CTL_DEL:
/* Handcraft a message for the server that requests */
/* deleting the disk with the specified ID */
msg.rd_type = htons(RD_MSG_DREQ);/* Request deletion */
msg.rd_status = htons(0);
msg.rd_seq = 0; /* rdscomm will insert sequence # later */
to = msg.rd_id;
memset(to, NULLCH, RD_IDLEN); /* Initialize to zeroes */
from = rdptr->rd_id;
while ( (*to++ = *from++) != NULLCH ) { /* copy ID */
;
}
/* Send message and receive response */
retval = rdscomm((struct rd_msg_hdr *)&msg,
sizeof(struct rd_msg_dreq),
(struct rd_msg_hdr *)&resp,
sizeof(struct rd_msg_dres),
rdptr);
/* Check response */
if (retval == SYSERR) {
return SYSERR;
} else if (retval == TIMEOUT) {
kprintf("Timeout during remote file delete\n\r");
return SYSERR;
} else if (ntohs(resp.rd_status) != 0) {
return SYSERR;
}
/* Close local device */
return rdsclose(devptr);
default:
kprintf("rfsControl: function %d not valid\n\r", func);
return SYSERR;
}
return OK;
}

108
device/rds/rdsinit.c

@ -0,0 +1,108 @@
/* rdsinit.c - rdsinit */
#include <xinu.h>
struct rdscblk rdstab[Nrds];
/*------------------------------------------------------------------------
* rdsinit - Initialize the remote disk system device
*------------------------------------------------------------------------
*/
devcall rdsinit (
struct dentry *devptr /* Entry in device switch table */
)
{
struct rdscblk *rdptr; /* Ptr to device contol block */
struct rdbuff *bptr; /* Ptr to buffer in memory */
/* used to form linked list */
struct rdbuff *pptr; /* Ptr to previous buff on list */
struct rdbuff *buffend; /* Last address in buffer memory*/
uint32 size; /* Total size of memory needed */
/* buffers */
/* Obtain address of control block */
rdptr = &rdstab[devptr->dvminor];
/* Set control block to unused */
rdptr->rd_state = RD_FREE;
/* Create the resprocess and leave it suspended. */
/* Note: the process cannot be resumed because */
/* device initialization occurs before interrupts */
/* are enabled. */
rdptr->rd_comproc = create(rdsprocess, RD_STACK, RD_PRIO,
"rdsproc", 1, rdptr);
if (rdptr->rd_comproc == SYSERR) {
panic("Cannot create remote disk process");
}
rdptr->rd_comruns = FALSE;
rdptr->rd_id[0] = NULLCH;
/* Set initial message sequence number */
rdptr->rd_seq = 1;
/* Initialize request queue and cache to empty */
rdptr->rd_rhnext = (struct rdbuff *) &rdptr->rd_rtnext;
rdptr->rd_rhprev = (struct rdbuff *)NULL;
rdptr->rd_rtnext = (struct rdbuff *)NULL;
rdptr->rd_rtprev = (struct rdbuff *) &rdptr->rd_rhnext;
rdptr->rd_chnext = (struct rdbuff *) &rdptr->rd_ctnext;
rdptr->rd_chprev = (struct rdbuff *)NULL;
rdptr->rd_ctnext = (struct rdbuff *)NULL;
rdptr->rd_ctprev = (struct rdbuff *) &rdptr->rd_chnext;
/* Allocate memory for a set of buffers (actually request */
/* blocks and link them to form the initial free list */
size = sizeof(struct rdbuff) * RD_BUFFS;
bptr = (struct rdbuff *)getmem(size);
rdptr->rd_free = bptr;
if ((int32)bptr == SYSERR) {
panic("Cannot allocate memory for remote disk buffers");
}
pptr = (struct rdbuff *) NULL; /* To avoid a compiler warning */
buffend = (struct rdbuff *) ((char *)bptr + size);
while (bptr < buffend) { /* walk through memory */
pptr = bptr;
bptr = (struct rdbuff *)
(sizeof(struct rdbuff)+ (char *)bptr);
pptr->rd_status = RD_INVALID; /* Buffer is empty */
pptr->rd_next = bptr; /* Point to next buffer */
}
pptr->rd_next = (struct rdbuff *) NULL; /* Last buffer on list */
/* Create the request list and available buffer semaphores */
rdptr->rd_availsem = semcreate(RD_BUFFS);
rdptr->rd_reqsem = semcreate(0);
/* Set the server IP address, server port, and local port */
if ( dot2ip(RD_SERVER_IP, &rdptr->rd_ser_ip) == SYSERR ) {
panic("invalid IP address for remote disk server");
}
/* Set the port numbers */
rdptr->rd_ser_port = RD_SERVER_PORT;
rdptr->rd_loc_port = RD_LOC_PORT + devptr->dvminor;
/* Specify that the server port is not yet registered */
rdptr->rd_registered = FALSE;
return OK;
}

93
device/rds/rdsopen.c

@ -0,0 +1,93 @@
/* rdsopen.c - rdsopen */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdsopen - Open a remote disk device and specify an ID to use
*------------------------------------------------------------------------
*/
devcall rdsopen (
struct dentry *devptr, /* Entry in device switch table */
char *diskid, /* Disk ID to use */
char *mode /* Unused for a remote disk */
)
{
struct rdscblk *rdptr; /* Ptr to control block entry */
struct rd_msg_oreq msg; /* Message to be sent */
struct rd_msg_ores resp; /* Buffer to hold response */
int32 retval; /* Return value from rdscomm */
int32 len; /* Counts chars in diskid */
char *idto; /* Ptr to ID string copy */
char *idfrom; /* Pointer into ID string */
rdptr = &rdstab[devptr->dvminor];
/* Reject if device is already open */
if (rdptr->rd_state != RD_FREE) {
return SYSERR;
}
rdptr->rd_state = RD_PEND;
/* Copy disk ID into free table slot */
idto = rdptr->rd_id;
idfrom = diskid;
len = 0;
while ( (*idto++ = *idfrom++) != NULLCH) {
len++;
if (len >= RD_IDLEN) { /* ID string is too long */
return SYSERR;
}
}
/* Verify that name is non-null */
if (len == 0) {
return SYSERR;
}
/* Hand-craft an open request message to be sent to the server */
msg.rd_type = htons(RD_MSG_OREQ);/* Request an open */
msg.rd_status = htons(0);
msg.rd_seq = 0; /* Rdscomm fills in an entry */
idto = msg.rd_id;
memset(idto, NULLCH, RD_IDLEN);/* initialize ID to zero bytes */
idfrom = diskid;
while ( (*idto++ = *idfrom++) != NULLCH ) { /* Copy ID to req. */
;
}
/* Send message and receive response */
retval = rdscomm((struct rd_msg_hdr *)&msg,
sizeof(struct rd_msg_oreq),
(struct rd_msg_hdr *)&resp,
sizeof(struct rd_msg_ores),
rdptr );
/* Check response */
if (retval == SYSERR) {
rdptr->rd_state = RD_FREE;
return SYSERR;
} else if (retval == TIMEOUT) {
kprintf("Timeout during remote file open\n\r");
rdptr->rd_state = RD_FREE;
return SYSERR;
} else if (ntohs(resp.rd_status) != 0) {
rdptr->rd_state = RD_FREE;
return SYSERR;
}
/* Change state of device to indicate currently open */
rdptr->rd_state = RD_OPEN;
/* Return device descriptor */
return devptr->dvnum;
}

212
device/rds/rdsprocess.c

@ -0,0 +1,212 @@
/* rdsprocess.c - rdsprocess */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdsprocess - High-priority background process that repeatedly
* extracts an item from the request queue, sends the
* request to the remote disk server, and handles the
* response, including caching responses blocks
*------------------------------------------------------------------------
*/
void rdsprocess (
struct rdscblk *rdptr /* Ptr to device control block */
)
{
struct rd_msg_wreq msg; /* Message to be sent */
/* (includes data area) */
struct rd_msg_rres resp; /* Buffer to hold response */
/* (includes data area) */
int32 retval; /* Return value from rdscomm */
char *idto; /* Ptr to ID string copy */
char *idfrom; /* Ptr into ID string */
struct rdbuff *bptr; /* Ptr to buffer at the head of */
/* the request queue */
struct rdbuff *nptr; /* Ptr to next buffer on the */
/* request queue */
struct rdbuff *pptr; /* Ptr to previous buffer */
struct rdbuff *qptr; /* Ptr that runs along the */
/* request queue */
int32 i; /* Loop index */
while (TRUE) { /* Do forever */
/* Wait until the request queue contains a node */
wait(rdptr->rd_reqsem);
bptr = rdptr->rd_rhnext;
/* Use operation in request to determine action */
switch (bptr->rd_op) {
case RD_OP_READ:
/* Build a read request message for the server */
msg.rd_type = htons(RD_MSG_RREQ); /* Read request */
msg.rd_status = htons(0);
msg.rd_seq = 0; /* Rdscomm fills in an entry */
idto = msg.rd_id;
memset(idto, NULLCH, RD_IDLEN);/* Initialize ID to zero */
idfrom = rdptr->rd_id;
while ( (*idto++ = *idfrom++) != NULLCH ) { /* Copy ID */
;
}
/* Send the message and receive a response */
retval = rdscomm((struct rd_msg_hdr *)&msg,
sizeof(struct rd_msg_rreq),
(struct rd_msg_hdr *)&resp,
sizeof(struct rd_msg_rres),
rdptr );
/* Check response */
if ( (retval == SYSERR) || (retval == TIMEOUT) ||
(ntohs(resp.rd_status) != 0) ) {
panic("Failed to contact remote disk server");
}
/* Copy data from the reply into the buffer */
for (i=0; i<RD_BLKSIZ; i++) {
bptr->rd_block[i] = resp.rd_data[i];
}
/* Unlink buffer from the request queue */
nptr = bptr->rd_next;
pptr = bptr->rd_prev;
nptr->rd_prev = bptr->rd_prev;
pptr->rd_next = bptr->rd_next;
/* Insert buffer in the cache */
pptr = (struct rdbuff *) &rdptr->rd_chnext;
nptr = pptr->rd_next;
bptr->rd_next = nptr;
bptr->rd_prev = pptr;
pptr->rd_next = bptr;
nptr->rd_prev = bptr;
/* Initialize reference count */
bptr->rd_refcnt = 1;
/* Signal the available semaphore */
signal(rdptr->rd_availsem);
/* Send a message to waiting process */
send(bptr->rd_pid, (uint32)bptr);
/* If other processes are waiting to read the */
/* block, notify them and remove the request */
qptr = rdptr->rd_rhnext;
while (qptr != (struct rdbuff *)&rdptr->rd_rtnext) {
if (qptr->rd_blknum == bptr->rd_blknum) {
bptr->rd_refcnt++;
send(qptr->rd_pid,(uint32)bptr);
/* Unlink request from queue */
pptr = qptr->rd_prev;
nptr = qptr->rd_next;
pptr->rd_next = bptr->rd_next;
nptr->rd_prev = bptr->rd_prev;
/* Move buffer to the free list */
qptr->rd_next = rdptr->rd_free;
rdptr->rd_free = qptr;
signal(rdptr->rd_availsem);
break;
}
qptr = qptr->rd_next;
}
break;
case RD_OP_WRITE:
/* Build a write request message for the server */
msg.rd_type = htons(RD_MSG_WREQ); /* Write request*/
msg.rd_blk = bptr->rd_blknum;
msg.rd_status = htons(0);
msg.rd_seq = 0; /* Rdscomb fills in an entry */
idto = msg.rd_id;
memset(idto, NULLCH, RD_IDLEN);/* Initialize ID to zero */
idfrom = rdptr->rd_id;
while ( (*idto++ = *idfrom++) != NULLCH ) { /* Copy ID */
;
}
for (i=0; i<RD_BLKSIZ; i++) {
msg.rd_data[i] = bptr->rd_block[i];
}
/* Unlink buffer from request queue */
nptr = bptr->rd_next;
pptr = bptr->rd_prev;
pptr->rd_next = nptr;
nptr->rd_prev = pptr;
/* Insert buffer in the cache */
pptr = (struct rdbuff *) &rdptr->rd_chnext;
nptr = pptr->rd_next;
bptr->rd_next = nptr;
bptr->rd_prev = pptr;
pptr->rd_next = bptr;
nptr->rd_prev = bptr;
/* Declare that buffer is eligible for reuse */
bptr->rd_refcnt = 0;
signal(rdptr->rd_availsem);
/* Send the message and receive a response */
retval = rdscomm((struct rd_msg_hdr *)&msg,
sizeof(struct rd_msg_wreq),
(struct rd_msg_hdr *)&resp,
sizeof(struct rd_msg_wres),
rdptr );
/* Check response */
if ( (retval == SYSERR) || (retval == TIMEOUT) ||
(ntohs(resp.rd_status) != 0) ) {
panic("failed to contact remote disk server");
}
break;
case RD_OP_SYNC:
/* Send a message to the waiting process */
send(bptr->rd_pid, OK);
/* Unlink buffer from the request queue */
nptr = bptr->rd_next;
pptr = bptr->rd_prev;
nptr->rd_prev = bptr->rd_prev;
pptr->rd_next = bptr->rd_next;
/* Insert buffer into the free list */
bptr->rd_next = rdptr->rd_free;
rdptr->rd_free = bptr;
signal(rdptr->rd_availsem);
break;
}
}
}

130
device/rds/rdsread.c

@ -0,0 +1,130 @@
/* rdsread.c - rdsread */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdsread - Read a block from a remote disk
*------------------------------------------------------------------------
*/
devcall rdsread (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer to hold disk block */
int32 blk /* Block number of block to read*/
)
{
struct rdscblk *rdptr; /* Pointer to control block */
struct rdbuff *bptr; /* Pointer to buffer possibly */
/* in the request list */
struct rdbuff *nptr; /* Pointer to "next" node on a */
/* list */
struct rdbuff *pptr; /* Pointer to "previous" node */
/* on a list */
struct rdbuff *cptr; /* Pointer that walks the cache */
/* If device not currently in use, report an error */
rdptr = &rdstab[devptr->dvminor];
if (rdptr->rd_state != RD_OPEN) {
return SYSERR;
}
/* Ensure rdsprocess is runnning */
if ( ! rdptr->rd_comruns ) {
rdptr->rd_comruns = TRUE;
resume(rdptr->rd_comproc);
}
/* Search the cache for specified block */
bptr = rdptr->rd_chnext;
while (bptr != (struct rdbuff *)&rdptr->rd_ctnext) {
if (bptr->rd_blknum == blk) {
if (bptr->rd_status == RD_INVALID) {
break;
}
memcpy(buff, bptr->rd_block, RD_BLKSIZ);
return OK;
}
bptr = bptr->rd_next;
}
/* Search the request list for most recent occurrence of block */
bptr = rdptr->rd_rtprev; /* Start at tail of list */
while (bptr != (struct rdbuff *)&rdptr->rd_rhnext) {
if (bptr->rd_blknum == blk) {
/* If most recent request for block is write, copy data */
if (bptr->rd_op == RD_OP_WRITE) {
memcpy(buff, bptr->rd_block, RD_BLKSIZ);
return OK;
}
break;
}
bptr = bptr->rd_prev;
}
/* Allocate a buffer and add read request to tail of req. queue */
bptr = rdsbufalloc(rdptr);
bptr->rd_op = RD_OP_READ;
bptr->rd_refcnt = 1;
bptr->rd_blknum = blk;
bptr->rd_status = RD_INVALID;
bptr->rd_pid = getpid();
/* Insert new request into list just before tail */
pptr = rdptr->rd_rtprev;
rdptr->rd_rtprev = bptr;
bptr->rd_next = pptr->rd_next;
bptr->rd_prev = pptr;
pptr->rd_next = bptr;
/* Prepare to receive message when read completes */
recvclr();
/* Signal the semaphore to start communication */
signal(rdptr->rd_reqsem);
/* Block to wait for a message */
bptr = (struct rdbuff *)receive();
if (bptr == (struct rdbuff *)SYSERR) {
return SYSERR;
}
memcpy(buff, bptr->rd_block, RD_BLKSIZ);
bptr->rd_refcnt--;
if (bptr->rd_refcnt <= 0) {
/* Look for previous item in cache with the same block */
/* number to see if this item was only being kept */
/* until pending read completed */
cptr = rdptr->rd_chnext;
while (cptr != bptr) {
if (cptr->rd_blknum == blk) {
/* Unlink from cache */
pptr = bptr->rd_prev;
nptr = bptr->rd_next;
pptr->rd_next = nptr;
nptr->rd_prev = pptr;
/* Add to the free list */
bptr->rd_next = rdptr->rd_free;
rdptr->rd_free = bptr;
break;
}
cptr = cptr->rd_next;
}
}
return OK;
}

97
device/rds/rdswrite.c

@ -0,0 +1,97 @@
/* rdswrite.c - rdswrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* rdswrite - Write a block to a remote disk
*------------------------------------------------------------------------
*/
devcall rdswrite (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer that holds a disk blk */
int32 blk /* Block number to write */
)
{
struct rdscblk *rdptr; /* Pointer to control block */
struct rdbuff *bptr; /* Pointer to buffer on a list */
struct rdbuff *pptr; /* Ptr to previous buff on list */
struct rdbuff *nptr; /* Ptr to next buffer on list */
bool8 found; /* Was buff found during search?*/
/* If device not currently in use, report an error */
rdptr = &rdstab[devptr->dvminor];
if (rdptr->rd_state != RD_OPEN) {
return SYSERR;
}
/* Ensure rdsprocess is runnning */
if ( ! rdptr->rd_comruns ) {
rdptr->rd_comruns = TRUE;
resume(rdptr->rd_comproc);
}
/* If request queue already contains a write request */
/* for the block, replace the contents */
bptr = rdptr->rd_rhnext;
while (bptr != (struct rdbuff *)&rdptr->rd_rtnext) {
if ( (bptr->rd_blknum == blk) &&
(bptr->rd_op == RD_OP_WRITE) ) {
memcpy(bptr->rd_block, buff, RD_BLKSIZ);
return OK;
}
bptr = bptr->rd_next;
}
/* Search cache for cached copy of block */
bptr = rdptr->rd_chnext;
found = FALSE;
while (bptr != (struct rdbuff *)&rdptr->rd_ctnext) {
if (bptr->rd_blknum == blk) {
if (bptr->rd_refcnt <= 0) {
pptr = bptr->rd_prev;
nptr = bptr->rd_next;
/* Unlink node from cache list and reset*/
/* the available semaphore accordingly*/
pptr->rd_next = bptr->rd_next;
nptr->rd_prev = bptr->rd_prev;
semreset(rdptr->rd_availsem,
semcount(rdptr->rd_availsem) - 1);
found = TRUE;
}
break;
}
bptr = bptr->rd_next;
}
if ( !found ) {
bptr = rdsbufalloc(rdptr);
}
/* Create a write request */
memcpy(bptr->rd_block, buff, RD_BLKSIZ);
bptr->rd_op = RD_OP_WRITE;
bptr->rd_refcnt = 0;
bptr->rd_blknum = blk;
bptr->rd_status = RD_VALID;
bptr->rd_pid = getpid();
/* Insert new request into list just before tail */
pptr = rdptr->rd_rtprev;
rdptr->rd_rtprev = bptr;
bptr->rd_next = pptr->rd_next;
bptr->rd_prev = pptr;
pptr->rd_next = bptr;
/* Signal semaphore to start communication process */
signal(rdptr->rd_reqsem);
return OK;
}

32
device/rfs/rflclose.c

@ -0,0 +1,32 @@
/* rflclose.c - rflclose */
#include <xinu.h>
/*------------------------------------------------------------------------
* rflclose - Close a remote file device
*------------------------------------------------------------------------
*/
devcall rflclose (
struct dentry *devptr /* Entry in device switch table */
)
{
struct rflcblk *rfptr; /* Pointer to control block */
/* Wait for exclusive access */
wait(Rf_data.rf_mutex);
/* Verify remote file device is open */
rfptr = &rfltab[devptr->dvminor];
if (rfptr->rfstate == RF_FREE) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Mark device closed */
rfptr->rfstate = RF_FREE;
signal(Rf_data.rf_mutex);
return OK;
}

23
device/rfs/rflgetc.c

@ -0,0 +1,23 @@
/* rflgetc.c - rflgetc */
#include <xinu.h>
/*------------------------------------------------------------------------
* rflgetc - Read one character from a remote file
*------------------------------------------------------------------------
*/
devcall rflgetc(
struct dentry *devptr /* Entry in device switch table */
)
{
char ch; /* Character to read */
int32 retval; /* Return value */
retval = rflread(devptr, &ch, 1);
if (retval != 1) {
return SYSERR;
}
return (devcall)ch;
}

29
device/rfs/rflinit.c

@ -0,0 +1,29 @@
/* rflinit.c - rflinit */
#include <xinu.h>
struct rflcblk rfltab[Nrfl]; /* Remote file control blocks */
/*------------------------------------------------------------------------
* rflinit - Initialize a remote file device
*------------------------------------------------------------------------
*/
devcall rflinit(
struct dentry *devptr /* Entry in device switch table */
)
{
struct rflcblk *rflptr; /* Ptr. to control block entry */
int32 i; /* Walks through name arrary */
rflptr = &rfltab[ devptr->dvminor ];
/* Initialize entry to unused */
rflptr->rfstate = RF_FREE;
rflptr->rfdev = devptr->dvnum;
for (i=0; i<RF_NAMLEN; i++) {
rflptr->rfname[i] = NULLCH;
}
rflptr->rfpos = rflptr->rfmode = 0;
return OK;
}

19
device/rfs/rflputc.c

@ -0,0 +1,19 @@
/* rflputc.c - rflputc */
#include <xinu.h>
/*------------------------------------------------------------------------
* rflputc - Write one character to a remote file
*------------------------------------------------------------------------
*/
devcall rflputc(
struct dentry *devptr, /* Entry in device switch table */
char ch /* Character to write */
)
{
if (rflwrite(devptr, &ch, 1) != 1) {
return SYSERR;
}
return OK;
}

100
device/rfs/rflread.c

@ -0,0 +1,100 @@
/* rflread.c - rflread */
#include <xinu.h>
/*------------------------------------------------------------------------
* rflread - Read data from a remote file
*------------------------------------------------------------------------
*/
devcall rflread (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer of bytes */
int32 count /* Count of bytes to read */
)
{
struct rflcblk *rfptr; /* Pointer to control block */
int32 retval; /* Return value */
struct rf_msg_rreq msg; /* Request message to send */
struct rf_msg_rres resp; /* Buffer for response */
int32 i; /* Counts bytes copied */
char *from, *to; /* Used during name copy */
int32 len; /* Length of name */
/* Wait for exclusive access */
wait(Rf_data.rf_mutex);
/* Verify count is legitimate */
if ( (count <= 0) || (count > RF_DATALEN) ) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Verify pseudo-device is in use */
rfptr = &rfltab[devptr->dvminor];
/* If device not currently in use, report an error */
if (rfptr->rfstate == RF_FREE) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Verify pseudo-device allows reading */
if ((rfptr->rfmode & RF_MODE_R) == 0) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Form read request */
msg.rf_type = htons(RF_MSG_RREQ);
msg.rf_status = htons(0);
msg.rf_seq = 0; /* Rfscomm will set sequence */
from = rfptr->rfname;
to = msg.rf_name;
memset(to, NULLCH, RF_NAMLEN); /* Start name as all zero bytes */
len = 0;
while ( (*to++ = *from++) ) { /* Copy name to request */
if (++len >= RF_NAMLEN) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
}
msg.rf_pos = htonl(rfptr->rfpos);/* Set file position */
msg.rf_len = htonl(count); /* Set count of bytes to read */
/* Send message and receive response */
retval = rfscomm((struct rf_msg_hdr *)&msg,
sizeof(struct rf_msg_rreq),
(struct rf_msg_hdr *)&resp,
sizeof(struct rf_msg_rres) );
/* Check response */
if (retval == SYSERR) {
signal(Rf_data.rf_mutex);
return SYSERR;
} else if (retval == TIMEOUT) {
kprintf("Timeout during remote file read\n");
signal(Rf_data.rf_mutex);
return SYSERR;
} else if (ntohs(resp.rf_status) != 0) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Copy data to application buffer and update file position */
for (i=0; i<ntohl(resp.rf_len); i++) {
*buff++ = resp.rf_data[i];
}
rfptr->rfpos += ntohl(resp.rf_len);
signal(Rf_data.rf_mutex);
return ntohl(resp.rf_len);
}

33
device/rfs/rflseek.c

@ -0,0 +1,33 @@
/* rflseek.c - rflseek */
#include <xinu.h>
/*------------------------------------------------------------------------
* rflseek - Change the current position in an open file
*------------------------------------------------------------------------
*/
devcall rflseek (
struct dentry *devptr, /* Entry in device switch table */
uint32 pos /* New file position */
)
{
struct rflcblk *rfptr; /* Pointer to control block */
/* Wait for exclusive access */
wait(Rf_data.rf_mutex);
/* Verify remote file device is open */
rfptr = &rfltab[devptr->dvminor];
if (rfptr->rfstate == RF_FREE) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Set the new position */
rfptr->rfpos = pos;
signal(Rf_data.rf_mutex);
return OK;
}

97
device/rfs/rflwrite.c

@ -0,0 +1,97 @@
/* rflwrite.c - rflwrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* rflwrite - Write data to a remote file
*------------------------------------------------------------------------
*/
devcall rflwrite (
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer of bytes */
int32 count /* Count of bytes to write */
)
{
struct rflcblk *rfptr; /* Pointer to control block */
int32 retval; /* Return value */
struct rf_msg_wreq msg; /* Request message to send */
struct rf_msg_wres resp; /* Buffer for response */
char *from, *to; /* Used to copy name */
int i; /* Counts bytes copied into req */
int32 len; /* Length of name */
/* Wait for exclusive access */
wait(Rf_data.rf_mutex);
/* Verify count is legitimate */
if ( (count <= 0) || (count > RF_DATALEN) ) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Verify pseudo-device is in use and mode allows writing */
rfptr = &rfltab[devptr->dvminor];
if ( (rfptr->rfstate == RF_FREE) ||
! (rfptr->rfmode & RF_MODE_W) ) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Form write request */
msg.rf_type = htons(RF_MSG_WREQ);
msg.rf_status = htons(0);
msg.rf_seq = 0; /* Rfscomm will set sequence */
from = rfptr->rfname;
to = msg.rf_name;
memset(to, NULLCH, RF_NAMLEN); /* Start name as all zero bytes */
len = 0;
while ( (*to++ = *from++) ) { /* Copy name to request */
if (++len >= RF_NAMLEN) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
}
while ( (*to++ = *from++) ) { /* Copy name into request */
;
}
msg.rf_pos = htonl(rfptr->rfpos);/* Set file position */
msg.rf_len = htonl(count); /* Set count of bytes to write */
for (i=0; i<count; i++) { /* Copy data into message */
msg.rf_data[i] = *buff++;
}
while (i < RF_DATALEN) {
msg.rf_data[i++] = NULLCH;
}
/* Send message and receive response */
retval = rfscomm((struct rf_msg_hdr *)&msg,
sizeof(struct rf_msg_wreq),
(struct rf_msg_hdr *)&resp,
sizeof(struct rf_msg_wres) );
/* Check response */
if (retval == SYSERR) {
signal(Rf_data.rf_mutex);
return SYSERR;
} else if (retval == TIMEOUT) {
kprintf("Timeout during remote file read\n");
signal(Rf_data.rf_mutex);
return SYSERR;
} else if (ntohs(resp.rf_status) != 0) {
signal(Rf_data.rf_mutex);
return SYSERR;
}
/* Report results to caller */
rfptr->rfpos += ntohl(resp.rf_len);
signal(Rf_data.rf_mutex);
return ntohl(resp.rf_len);
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save