diff --git a/.gitignore b/.gitignore index 07d0aed..733427d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,5 @@ .gitignore -*.map -*.rel -*.rst -*.sym -*.asm -*.bin -*.ihx -*.ihex -*.lst -*.mem -!rtlplayground.mem -*.lk +output/ html_data.c html_data.h tools/httpd_sim diff --git a/Makefile b/Makefile index 3b0c892..cdfb02d 100644 --- a/Makefile +++ b/Makefile @@ -12,14 +12,19 @@ AFLAGS= -plosgff SUBDIRS := tools uip httpd SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS)) -all: $(SUBDIRS) rtlplayground.bin +BUILDDIR = output/ + +all: create_build_dir $(SUBDIRS) $(BUILDDIR)rtlplayground.bin + +create_build_dir: + mkdir -p $(BUILDDIR) SRCS = rtlplayground.c rtl837x_flash.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c rtl837x_stp.c -OBJS = ${SRCS:.c=.rel} -OBJS += uip/timer.rel uip/uip-fw.rel uip/uip-neighbor.rel uip/uip-split.rel uip/uip.rel uip/uip_arp.rel uip/uiplib.rel httpd/httpd.rel httpd/page_impl.rel +OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} +OBJS += uip/$(BUILDDIR)/timer.rel uip/$(BUILDDIR)/uip-fw.rel uip/$(BUILDDIR)/uip-neighbor.rel uip/$(BUILDDIR)/uip-split.rel uip/$(BUILDDIR)/uip.rel uip/$(BUILDDIR)/uip_arp.rel uip/$(BUILDDIR)/uiplib.rel httpd/$(BUILDDIR)/httpd.rel httpd/$(BUILDDIR)/page_impl.rel html_data.c html_data.h: html tools - tools/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data + tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -b BANK1 -d html -p html_data httpd: html_data.h @@ -29,34 +34,33 @@ $(SUBDIRS): clean: -make -C uip clean -make -C httpd clean - -rm html_data.c html_data.c - if [ -e rtlplayground.bin ]; then rm rtlplayground.bin; fi - if [ -e rtlplayground.asm ]; then rm rtlplayground.asm; fi - -rm *.ihx *.lk *.lst *.map *.mem *.rel *.rst *.sym *.bin + -rm html_data.c html_data.h + -rm -r $(BUILDDIR) +$(BUILDDIR)crtstart.rel: crtstart.asm + $(ASM) $(AFLAGS) -o $@ $< -%.rel: %.c - $(CC) $(CC_FLAGS) -c $< +$(BUILDDIR)%.rel: %.c + $(CC) $(CC_FLAGS) -o $@ -c $< -%.rel: %.asm - ${ASM} ${AFLAGS} $^ +$(BUILDDIR)%.rel: $(BUILDDIR)%.asm + ${ASM} ${AFLAGS} -o $@ $< # mv -f $(addprefix $(basename $^), .lst .rel .sym) . -rtlplayground.ihx: crtstart.rel $(OBJS) +$(BUILDDIR)rtlplayground.ihx: $(BUILDDIR)crtstart.rel $(OBJS) $(CC) $(CC_FLAGS) -Wl-bHOME=${BOOTLOADER_ADDRESS} -Wl-bBANK1=0x14000 -Wl-r -o $@ $^ -%.img: %.ihx +$(BUILDDIR)rtlplayground.img: $(BUILDDIR)rtlplayground.ihx objcopy --input-target=ihex -O binary $< $@ -%.bin: %.img +$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlplayground.img if [ -e $@ ]; then rm $@; fi echo "0000000: 00 40" | xxd -r - $@ cat $< >> $@ truncate --size=16K $@ dd if=$< skip=80 bs=1024 >>$@ - tools/fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ - tools/fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@ + tools/$(BUILDDIR)fileadder -a $(CONFIG_LOCATION) -s $(IMAGESIZE) -d config.txt $@ + tools/$(BUILDDIR)fileadder -a $(HTML_LOCATION) -s $(IMAGESIZE) -d html -p html_data $@ -.PHONY: clean all $(SUBDIRS) -.PRECIOUS: %.rel %.ihx .img +.PHONY: clean all $(SUBDIRS) \ No newline at end of file diff --git a/cmd_parser.c b/cmd_parser.c index 86fa251..68a01f4 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -514,7 +514,7 @@ void cmd_parser(void) __banked } if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'e') { print_string("\nFLASH erase\n"); - flash_block_erase(0x20000); + flash_sector_erase(0x20000); } if (cmd_compare(0, "flash") && cmd_words_b[1] > 0 && cmd_buffer[cmd_words_b[1]] == 'w') { print_string("\nFLASH write\n"); diff --git a/html/index.html b/html/index.html index e6f90d7..485e607 100644 --- a/html/index.html +++ b/html/index.html @@ -9,7 +9,9 @@ +
  • Port Aggregation
  • +
  • Mirroring
  • +
  • Firmware Update
  • Switch Configuration

    diff --git a/httpd/Makefile b/httpd/Makefile index 397f46c..d801ddf 100644 --- a/httpd/Makefile +++ b/httpd/Makefile @@ -3,21 +3,26 @@ CC_FLAGS = -mmcs51 -I. -I../uip ASM = sdas8051 AFLAGS= -plosgff +BUILDDIR = output/ + SRCS = httpd.c page_impl.c -OBJS = ${SRCS:.c=.rel} +OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} -all: $(OBJS) +all: create_build_dir $(OBJS) -%.asm: %.c - $(CC) $(CC_FLAGS) -c -S $< +create_build_dir: + mkdir -p $(BUILDDIR) -%.rel: %.asm +$(BUILDDIR)%.asm: %.c + $(CC) $(CC_FLAGS) -o $@ -c -S $< + +$(BUILDDIR)%.rel: $(BUILDDIR)%.asm ./treatasm.py $^ >$^.new mv $^.new $^ - ${ASM} ${AFLAGS} $^ + ${ASM} ${AFLAGS} -o $@ $^ clean: - rm .asm *.lst *.rel *.rst *.sym + rm -r $(BUILDDIR) .PHONY: all clean diff --git a/installer/Makefile b/installer/Makefile index 6e08556..d4cdc1a 100644 --- a/installer/Makefile +++ b/installer/Makefile @@ -6,29 +6,37 @@ CC_FLAGS = -mmcs51 ASM = sdas8051 AFLAGS= -plosgff +BUILDDIR = output/ + SRCS = installer.c -OBJS = ${SRCS:.c=.rel} +OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} -all: updatebuilder rtlplayground.bin +all: create_build_dir $(BUILDDIR)updatebuilder $(BUILDDIR)rtlplayground.bin -updatebuilder: updatebuilder.c +create_build_dir: + mkdir -p $(BUILDDIR) + +$(BUILDDIR)updatebuilder: updatebuilder.c gcc $^ -o $@ -installer.rel: installer.c - $(CC) $(CC_FLAGS) --code-loc ${CODE_LOCATION} -c $< +$(BUILDDIR)installer.rel: installer.c + $(CC) $(CC_FLAGS) --code-loc ${CODE_LOCATION} -o $@ -c $< -%.rel: %.asm - ${ASM} ${AFLAGS} $^ +$(BUILDDIR)crtstart.rel: crtstart.asm + $(ASM) $(AFLAGS) -o $@ $< -%.rel: %.c - $(CC) $(CC_FLAGS) -c $< +$(BUILDDIR)%.rel: $(BUILDDIR)%.asm + ${ASM} ${AFLAGS} -o $@ $^ -rtlinstaller.ihx: crtstart.rel $(OBJS) +$(BUILDDIR)%.rel: %.c + $(CC) $(CC_FLAGS) -o $@ -c $< + +$(BUILDDIR)rtlinstaller.ihx: $(BUILDDIR)crtstart.rel $(OBJS) $(CC) $(CC_FLAGS) -Wl-bHOME=${INSTALLER_ADDRESS} -Wl-r -o $@ $^ -rtlplayground.bin: rtlinstaller.ihx ../rtlplayground.bin - cp ../rtlplayground.bin . - ./updatebuilder -i $< rtlplayground.bin +$(BUILDDIR)rtlplayground.bin: $(BUILDDIR)rtlinstaller.ihx ../$(BUILDDIR)/rtlplayground.bin + cp ../$(BUILDDIR)/rtlplayground.bin $(BUILDDIR) + ./$(BUILDDIR)/updatebuilder -i $< $(BUILDDIR)rtlplayground.bin clean: - rm *.ihx *.lst *.rel *.rst *.sym *.lst *.map *.mem *.lk $(OBJS) installer.asm + rm -r $(BUILDDIR) diff --git a/rtl837x_flash.c b/rtl837x_flash.c index 566e25b..471116f 100644 --- a/rtl837x_flash.c +++ b/rtl837x_flash.c @@ -11,7 +11,16 @@ __xdata uint8_t dio_enabled; __xdata uint8_t markbuf[16]; extern __xdata uint16_t mpos; -#pragma codeseg BANK1 +// For the flash commands, see e.g. Windbond W25Q32JV datasheet +#define CMD_WRITE_STATUS 0x01 +#define CMD_PAGE_PROGRAM 0x02 +#define CMD_WRITE_ENABLE 0x06 +#define CMD_FREAD 0x0b +#define CMD_SECTOR_ERASE 0x20 +#define CMD_READ_SECURITY_REGS 0x48 +#define CMD_READ_UNIQUE_ID 0x4b +#define CMD_READ_JEDEC_ID 0x9f +#define CMD_FREAD_DIO 0xbb /* * Configure Memory Managed IO @@ -21,14 +30,14 @@ void flash_configure_mmio(void) // Set configuration for MMIO access by controller if (dio_enabled) { SFR_FLASH_MODEB = 0x18; - SFR_FLASH_CMD_R = 0xbb; // By default we read with Dual speed - SFR_FLASH_DUMMYCICLES = 4; + SFR_FLASH_CMD_R = CMD_FREAD_DIO; // By default we read with Dual speed + SFR_FLASH_DUMMYCYCLES = 4; return; } SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0xb; // By default we read with single speed - SFR_FLASH_DUMMYCICLES = 8; + SFR_FLASH_CMD_R = 0xb; // Default is Single IO + SFR_FLASH_DUMMYCYCLES = 8; } @@ -39,27 +48,26 @@ void flash_configure_mmio(void) * This configures fast single IO at 20.8 MHz when the CPU clock is at 20.8MHz * and 62.5MHz when the CPU clock is configured at 125MHz */ -void flash_init(uint8_t enable_dio) __banked +void flash_init(uint8_t enable_dio) { if (enable_dio) { - // Configure fast DIO via divider/DIO/SIOconfig = 4 and read-cmd being 0xbb (for mmio) SFR_FLASH_CONFIG = 9; // There may be a chip-select in here - SFR_FLASH_CONF_RCMD = 0xbb; + SFR_FLASH_CONF_RCMD = CMD_FREAD_DIO; SFR_FLASH_CONF_DIV = 4; } else { - // Configure fast read via divider = 8 and read-cmd being 0xb (for mmio) + // Configure fast read via divider = 8 and read-cmd being CMD_FREAD (for mmio) SFR_FLASH_CONFIG = 9; - SFR_FLASH_CONF_RCMD = 0xb; + SFR_FLASH_CONF_RCMD = CMD_FREAD; SFR_FLASH_CONF_DIV = 8; } // Test Controller Busy while(SFR_FLASH_EXEC_BUSY); // Write 0 to status register - SFR_FLASH_DUMMYCICLES = 8; + SFR_FLASH_DUMMYCYCLES = 8; SFR_FLASH_MODEB = 0; SFR_FLASH_TCONF = 0x19; - SFR_FLASH_CMD = 1; + SFR_FLASH_CMD = CMD_WRITE_STATUS; SFR_FLASH_DATA0 = 0; SFR_FLASH_EXEC_GO = 1; while(SFR_FLASH_EXEC_BUSY); @@ -86,14 +94,14 @@ uint8_t flash_read_status(void) } -void flash_read_uid(void) __banked +void flash_read_uid(void) { while (flash_read_status() & 0x1); // Set slow read mode for UID SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0x4b; - SFR_FLASH_DUMMYCICLES = 8; + SFR_FLASH_CMD_R = CMD_READ_UNIQUE_ID; + SFR_FLASH_DUMMYCYCLES = 8; // Transfer 4 bytes (command + 3 dummy bytes) SFR_FLASH_TCONF = 4; @@ -110,7 +118,7 @@ void flash_read_uid(void) __banked print_byte(SFR_FLASH_DATA24); SFR_FLASH_EXEC_GO = 1; - SFR_FLASH_DUMMYCICLES = 24; + SFR_FLASH_DUMMYCYCLES = 24; while(SFR_FLASH_EXEC_BUSY); print_byte(SFR_FLASH_DATA0); @@ -122,14 +130,14 @@ void flash_read_uid(void) __banked } -void flash_read_jedecid(void) __banked +void flash_read_jedecid(void) { while (flash_read_status() & 0x1); // Set read mode for JEDEC ID SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0x9f; - SFR_FLASH_DUMMYCICLES = 0; + SFR_FLASH_CMD_R = CMD_READ_JEDEC_ID; + SFR_FLASH_DUMMYCYCLES = 0; // Transfer 3 bytes back SFR_FLASH_TCONF = 0x13; @@ -144,12 +152,12 @@ void flash_read_jedecid(void) __banked // Reset slow read mode SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0xb; - SFR_FLASH_DUMMYCICLES = 8; + SFR_FLASH_CMD_R = CMD_FREAD; + SFR_FLASH_DUMMYCYCLES = 8; } -void flash_write_enable(void) __banked +void flash_write_enable(void) { short status; @@ -157,14 +165,16 @@ void flash_write_enable(void) __banked do { status = flash_read_status(); } while (status & 0x1); -// while (flash_read_status() & 0x1); SFR_FLASH_TCONF = 0x18; - SFR_FLASH_CMD = 6; -/* The following is explicitly set for SIO, is this necessary?: + SFR_FLASH_CMD = CMD_WRITE_ENABLE; + + /* The following makes sure that the PAGE_PROGRAM command, + * where the data to be written follows the command word directly + * works properly + */ SFR_FLASH_DUMMYCYCLES = 0; SFR_FLASH_MODEB = 0; -*/ SFR_FLASH_EXEC_GO = 1; // Wait for write status enabled @@ -174,7 +184,7 @@ void flash_write_enable(void) __banked } -void flash_dump(register uint32_t addr, register uint8_t len) __banked +void flash_dump(register uint32_t addr, register uint8_t len) { short status; do { @@ -185,12 +195,12 @@ void flash_dump(register uint32_t addr, register uint8_t len) __banked // Set fast read mode if (dio_enabled) { SFR_FLASH_MODEB = 0x18; - SFR_FLASH_CMD_R = 0xbb; - SFR_FLASH_DUMMYCICLES = 4; + SFR_FLASH_CMD_R = CMD_FREAD_DIO; + SFR_FLASH_DUMMYCYCLES = 4; } else { SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0xb; // Fast read - SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read? + SFR_FLASH_CMD_R = CMD_FREAD; // Fast read + SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read? } // Read 4 bytes SFR_FLASH_TCONF = 4; @@ -222,7 +232,7 @@ void flash_dump(register uint32_t addr, register uint8_t len) __banked * Reads bulk data of length len from the flash memory starging at address src * and writes the data into a buffer pointed to by dst in XMEM */ -void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len) __banked +void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len) { short status; do { @@ -232,12 +242,12 @@ void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, regist // Set fast read mode if (dio_enabled) { SFR_FLASH_MODEB = 0x18; - SFR_FLASH_CMD_R = 0xbb; - SFR_FLASH_DUMMYCICLES = 4; + SFR_FLASH_CMD_R = CMD_FREAD_DIO; + SFR_FLASH_DUMMYCYCLES = 4; } else { SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0xb; // Fast read - SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read? + SFR_FLASH_CMD_R = CMD_FREAD; // Fast read + SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read? } // Read 4 bytes SFR_FLASH_TCONF = 4; @@ -266,7 +276,7 @@ void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, regist } -void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark) __banked +void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark) { uint16_t status; do { @@ -276,12 +286,12 @@ void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t // Set fast read mode if (dio_enabled) { SFR_FLASH_MODEB = 0x18; - SFR_FLASH_CMD_R = 0xbb; - SFR_FLASH_DUMMYCICLES = 4; + SFR_FLASH_CMD_R = CMD_FREAD_DIO; + SFR_FLASH_DUMMYCYCLES = 4; } else { SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0xb; // Fast read - SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks after read? + SFR_FLASH_CMD_R = CMD_FREAD; // Fast read + SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks after read? } uint8_t i = 0; @@ -348,14 +358,14 @@ void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t } -void flash_read_security(uint32_t addr, uint8_t len) __banked +void flash_read_security(uint32_t addr, uint8_t len) { while (flash_read_status() & 0x1); // Set slow read mode SFR_FLASH_MODEB = 0x0; - SFR_FLASH_CMD_R = 0x48; // read security register - SFR_FLASH_DUMMYCICLES = 8; // Add 8 dummy clocks as for fast read + SFR_FLASH_CMD_R = CMD_READ_SECURITY_REGS; // read security register + SFR_FLASH_DUMMYCYCLES = 8; // Add 8 dummy clocks as for fast read // Transfer 4 bytes (command + 3byte address) SFR_FLASH_TCONF = 4; @@ -384,11 +394,11 @@ void flash_read_security(uint32_t addr, uint8_t len) __banked } -void flash_block_erase(uint32_t addr) __banked +void flash_sector_erase(uint32_t addr) { flash_write_enable(); SFR_FLASH_TCONF = 8; - SFR_FLASH_CMD = 0x20; + SFR_FLASH_CMD = CMD_SECTOR_ERASE; SFR_FLASH_ADDR16 = addr >> 16; SFR_FLASH_ADDR8 = addr >> 8; @@ -402,14 +412,14 @@ void flash_block_erase(uint32_t addr) __banked } -void flash_write_bytes(__xdata uint32_t addr, __xdata uint8_t *ptr, uint16_t len) __banked +void flash_write_bytes(__xdata uint32_t addr, __xdata uint8_t *ptr, uint16_t len) { - static __xdata uint8_t exit_loop = 0; + uint8_t exit_loop = 0; while(1) { flash_write_enable(); - SFR_FLASH_CMD = 2; - SFR_FLASH_TCONF = 0x40 | 8 | 2; // Bytes written is is 4, 8 enables write, 0x2 is unkown + SFR_FLASH_CMD = CMD_PAGE_PROGRAM; + SFR_FLASH_TCONF = 0x40 | 8 | 4; // Bytes written is is 4, 8 enables write, 0x40 is unkown // Last transfer? if (len < 5) { SFR_FLASH_TCONF = 8 | len; diff --git a/rtl837x_flash.h b/rtl837x_flash.h index 8e44385..f891f97 100644 --- a/rtl837x_flash.h +++ b/rtl837x_flash.h @@ -1,14 +1,14 @@ #ifndef _RTL837X_FLASH_H_ #define _RTL837X_FLASH_H_ -void flash_init(uint8_t enable_dio) __banked; -void flash_read_uid(void) __banked; -void flash_write_enable(void)__banked ; -void flash_dump(register uint32_t addr, register uint8_t len) __banked; -void flash_read_jedecid(void) __banked; -void flash_read_security(uint32_t addr, uint8_t len)__banked ; -void flash_block_erase(uint32_t addr) __banked; -void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len) __banked; -void flash_write_bytes(__xdata uint32_t addr, register __xdata uint8_t *ptr, register uint16_t len)__banked; -void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark) __banked; +void flash_init(uint8_t enable_dio); +void flash_read_uid(void); +void flash_write_enable(void); +void flash_dump(register uint32_t addr, register uint8_t len); +void flash_read_jedecid(void); +void flash_read_security(uint32_t addr, uint8_t len); +void flash_sector_erase(uint32_t addr); +void flash_read_bulk(register __xdata uint8_t *dst, __xdata uint32_t src, register uint16_t len); +void flash_write_bytes(__xdata uint32_t addr, register __xdata uint8_t *ptr, register uint16_t len); +void flash_find_mark(__xdata uint32_t src, register uint16_t len, __code uint8_t *mark); #endif diff --git a/rtl837x_sfr.h b/rtl837x_sfr.h index 314ea33..9a99ac7 100644 --- a/rtl837x_sfr.h +++ b/rtl837x_sfr.h @@ -71,7 +71,7 @@ __sfr __at(0xbc) SFR_FLASH_CONFIG; __sfr __at(0x9b) SFR_FLASH_CONF_DIV; __sfr __at(0x9c) SFR_FLASH_CONF_RCMD; -__sfr __at(0x9d) SFR_FLASH_DUMMYCICLES; +__sfr __at(0x9d) SFR_FLASH_DUMMYCYCLES; __sfr __at(0x9a) SFR_FLASH_MODEB; __sfr __at(0x9e) SFR_FLASH_TCONF; diff --git a/rtlplayground.mem b/rtlplayground.mem deleted file mode 100644 index acbb192..0000000 --- a/rtlplayground.mem +++ /dev/null @@ -1,29 +0,0 @@ -Internal RAM layout: - 0 1 2 3 4 5 6 7 8 9 A B C D E F -0x00:|0|0|0|0|0|0|0|0|a|a|a|a|a|a|a|a| -0x10:|c|c|c|d|d|d|d|d|d|d| | | | | | | -0x20:|B|T|b|b|b|b|b|b|b|b|b|b|b|b|b|b| -0x30:|b|b|b|b|e|e|e|e|e|e|e|e|f|f|f|f| -0x40:|f|f|f|f|f|g|g|g|g|g|g|g|g|g|g|g| -0x50:|g|h|h|h|h|h|h|h|h|h|h|h|h|i|i|i| -0x60:|i|i|i|i|i|i|i|j|j|j|j|j|j|j|j|j| -0x70:|j|j|j|j|j|Q|Q|Q|Q|Q|Q|Q|S|S|S|S| -0x80:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0x90:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0xa0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0xb0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0xc0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0xd0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0xe0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0xf0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S| -0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute - -16 bit mode initial stack starts at: 0x7c (sp set to 0x7b) with 132 bytes available. -The largest spare internal RAM space starts at 0x1a with 6 bytes available. - -Other memory: - Name Start End Size Max - ---------------- -------- -------- -------- -------- - PAGED EXT. RAM 0 256 - EXTERNAL RAM 0x0001 0x1b28 6952 16777216 - ROM/EPROM/FLASH 0x0000 0x1b85e 44067 16777216 diff --git a/tools/Makefile b/tools/Makefile index 60a80b2..87333ed 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,15 +1,20 @@ CC = gcc +CCFLAGS = -Wall -o +BUILDDIR = output/ -all: injector fileadder httpd_sim +all: create_build_dir $(BUILDDIR)injector $(BUILDDIR)fileadder $(BUILDDIR)httpd_sim + +create_build_dir: + mkdir -p $(BUILDDIR) clean: - rm *.o + rm -r $(BUILDDIR) -injector: injector.c - gcc $^ -o $@ +$(BUILDDIR)injector: injector.c + gcc $^ $(CCFLAGS) $@ -fileadder: fileadder.c - gcc $^ -o $@ +$(BUILDDIR)fileadder: fileadder.c + gcc $^ $(CCFLAGS) $@ -httpd_sim: httpd_sim.c httpd_sim.h - gcc $< -o $@ -I/usr/include/json-c -ljson-c +$(BUILDDIR)httpd_sim: httpd_sim.c httpd_sim.h + gcc $< $(CCFLAGS) $@ -I/usr/include/json-c -ljson-c diff --git a/tools/fileadder.c b/tools/fileadder.c index 2ce351e..84a2865 100644 --- a/tools/fileadder.c +++ b/tools/fileadder.c @@ -216,8 +216,6 @@ int replaceCalls(int pos) int main(int argc, char **argv) { - char * line = NULL; - size_t len = 0; struct arguments arguments; int arg_index; char tmpfilename[] = "image_XXXXXX"; diff --git a/tools/httpd_sim.c b/tools/httpd_sim.c index cb7792f..2a4f8d1 100644 --- a/tools/httpd_sim.c +++ b/tools/httpd_sim.c @@ -7,6 +7,7 @@ #include #include "httpd_sim.h" #include +#include #define PORTS 6 time_t last_called; @@ -14,6 +15,25 @@ time_t last_called; uint64_t txG[PORTS], txB[PORTS], rxG[PORTS], rxB[PORTS]; char txG_buff[20], txB_buff[20], rxG_buff[20], rxB_buff[20]; char num_buff[20]; +char upload_buffer[4194304]; // 4MB + +char *content_type = NULL; +char boundary[72]; + +char is_word(char *c, char *d) +{ + uint8_t i = 0; + + while (d[i] && (d[i] == c[i])) + i++; + + if (d[i]) + return 0; + if (c[i] != ' ' && c[i] != '\t' && c[i] != ':' && c[i] != '?' && c[i] != '=' && c[i] != '\n' && c[i] != '\r' && c[i]) + return 0; + return 1; +} + int hasSuffix(const char *str, const char *suffix) { @@ -70,13 +90,13 @@ void send_vlan(int s, int vlan) void send_status(int s) { - struct json_object *jobj, *ports, *v; + struct json_object *ports, *v; const char *jstring; char *header = "HTTP/1.1 200 OK\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n"; time_t now = time(NULL); - now == last_called ? last_called + 1 : now; // Make sure we don't divide by 0 for rates + now = last_called ? last_called + 1 : now; // Make sure we don't divide by 0 for rates ports = json_object_new_array_ext(PORTS); for (int i = 1; i <= PORTS; i++) { @@ -92,10 +112,10 @@ void send_status(int s) txB[i-1] += rate * (now - last_called) / 10000000; rxB[i-1] += rate * (now - last_called) / 10000000; } - sprintf(txG_buff, "0x%016x", txG[i-1]); - sprintf(txB_buff, "0x%016x", txB[i-1]); - sprintf(rxG_buff, "0x%016x", rxG[i-1]); - sprintf(rxB_buff, "0x%016x", rxB[i-1]); + sprintf(txG_buff, "0x%016lx", txG[i-1]); + sprintf(txB_buff, "0x%016lx", txB[i-1]); + sprintf(rxG_buff, "0x%016lx", rxG[i-1]); + sprintf(rxB_buff, "0x%016lx", rxB[i-1]); json_object_object_add(v, "txG", json_object_new_string(txG_buff)); json_object_object_add(v, "txB", json_object_new_string(txB_buff)); json_object_object_add(v, "rxG", json_object_new_string(rxG_buff)); @@ -145,7 +165,63 @@ struct Server serverConstructor(int port, void (*launch)(struct Server *server)) return server; } -void launch(struct Server *server) { +void send_not_found(int socket) { + char *response = "HTTP/1.1 404 Not found\r\n" + "Content-Type: text/html\r\n\r\n" + " Not Found" + "

    Not found!

    "; + write(socket, response, strlen(response)); +} + + +void send_bad_request(int socket) { + char *response = "HTTP/1.1 400 Bad Request\r\n" + "Content-Type: text/html\r\n\r\n" + " Bad Request" + "

    Bad Request!

    "; + write(socket, response, strlen(response)); +} + + +char *scan_header(char *p) +{ + while (*p != '\r' || *(p + 1) != '\n' || *(p + 2) != '\r' || *(p + 3) != '\n') { + if (!*p++) + break; + if (*p == '\n' && is_word(p + 1, "Content-Type:")) + content_type = p + 15; + } + if (content_type && is_word(content_type, "multipart/form-data; boundary")) { + printf("Found multiplart\n"); + content_type += 30; + uint8_t i = 0; + while (content_type[i] != '\r' && content_type[i] != '\n') { + boundary[i + 2] = content_type[i]; + i++; + } + // The boundary between parts is "--" + the boundary given in the header + boundary[0] = '-'; + boundary[1] = '-'; + boundary[i + 2] = 0; + } + + return p; +} + + +char *skip_boundary(char *p) +{ + while (*p) { + if (is_word(p, boundary)) + return p + strlen(boundary); + p++; + } + return p; +} + + +void launch(struct Server *server) +{ char buffer[BUFFER_SIZE]; FILE *inptr; @@ -153,88 +229,167 @@ void launch(struct Server *server) { for (int i=0; i < PORTS; i++) txG[i] = txB[i] = rxG[i] = rxB[i] = 0; - while (1) { - printf("=== Waiting for connection on port %d === \n", server->port); - int addrlen = sizeof(server->address); - int new_socket = accept(server->socket, (struct sockaddr*)&server->address, (socklen_t*)&addrlen); - ssize_t bytesRead = read(new_socket, buffer, BUFFER_SIZE - 1); - if (bytesRead >= 0) { - buffer[bytesRead] = '\0'; // Null terminate the string - puts(buffer); - - if (buffer[0] == 'G' && buffer[1] == 'E' && buffer[2] == 'T' && buffer[3] == ' ') { - printf("GET request\n"); - if (!strncmp(&buffer[4], "/status.json", 12)) { - printf("Status request\n"); - send_status(new_socket); - goto done; - } - if (!strncmp(&buffer[4], "/vlan.json?vid=", 15)) { - int vlan = atoi(&buffer[19]); - printf("VLAN request for %d\n", vlan); - send_vlan(new_socket, vlan); - goto done; - } - int i = 0; - while (!isspace(buffer[4 + i])) - i++; - buffer[4+i] = '\0'; + while (1) { + printf("=== Waiting for connection on port %d === \n", server->port); + int addrlen = sizeof(server->address); + int new_socket = accept(server->socket, (struct sockaddr*)&server->address, (socklen_t*)&addrlen); + ssize_t bytesRead = read(new_socket, buffer, BUFFER_SIZE - 1); + printf("bytesRead: %ld\n", bytesRead); + int filesize = 0; + char *mime; - printf("Serving file: >%s<\n", &buffer[5]); - inptr = fopen(&buffer[5], "rb"); - if (inptr == NULL) { - printf("Cannot open input file %s\n", &buffer[5]); - char *response = "HTTP/1.1 404 Not found\r\n" - "Content-Type: text/html\r\n\r\n" - " Not found" - "

    Not found!

    "; + if (bytesRead > 0) { + buffer[bytesRead] = '\0'; // Null terminate the string + puts(buffer); + + if (is_word(buffer, "GET")) { + printf("GET request\n"); + if (!strncmp(&buffer[4], "/status.json", 12)) { + printf("Status request\n"); + send_status(new_socket); + goto done; + } + if (!strncmp(&buffer[4], "/vlan.json?vid=", 15)) { + int vlan = atoi(&buffer[19]); + printf("VLAN request for %d\n", vlan); + send_vlan(new_socket, vlan); + goto done; + } + int i = 0; + while (!isspace(buffer[4 + i])) + i++; + buffer[4+i] = '\0'; + + printf("Serving file: >%s<\n", &buffer[5]); + inptr = fopen(&buffer[5], "rb"); + if (inptr == NULL) { + printf("Cannot open input file %s\n", &buffer[5]); + send_not_found(new_socket); + goto done; + } + + mime = getMime(&buffer[5]); + printf("MIME type: %s\n", mime); + + fseek(inptr, 0L, SEEK_END); + filesize = ftell(inptr); + printf("Filesize: %d\n", filesize); + rewind(inptr); + printf("Input file size: %d\n", filesize); + if (filesize > BUFFER_SIZE) { + printf("File too large.\n"); + goto done; + } + size_t bytes_read = fread(buffer, 1, sizeof(buffer), inptr); + + printf("Bytes read: %ld\n", bytes_read); + + if (bytes_read != filesize) { + printf("Error reading input file.\n"); + goto done; + } + fclose(inptr); + } else if (is_word(buffer, "POST")) { + printf("POST request\n"); + // Find end of request header + char *p = buffer; + boundary[0] ='\0'; + p = scan_header(p); + printf("Boundary: >%s<\n", boundary); + if (!*p || !content_type) { + printf("Bad request, no content type!\n"); + send_bad_request(new_socket); + goto done; + } + + printf("Bytes read %ld\n", bytesRead); + if (is_word(&buffer[5], "/upload")) { + printf("POST upload request\n"); + if (!boundary[0]) { + printf("Bad request, no boundary!\n"); + send_bad_request(new_socket); + goto done; + } + // We skip the intial parts as part of the header + do { + p = skip_boundary(p); + if (!*p) + goto bad_request; + p = scan_header(p); + if (!*p || !content_type) + goto bad_request; + } while (!is_word(content_type, "application/octet-stream")); + printf("Have content: >%s<\n", content_type); + + char *uptr = upload_buffer; + int bindex = 0; + int bptr = p - buffer; + do { + if (bptr >= bytesRead) { + bptr = 0; + bytesRead = read(new_socket, buffer, BUFFER_SIZE - 1); + printf("bytesRead: %ld\n", bytesRead); + if (!bytesRead) + break; + } + if (!boundary[bindex]) + break; + if (buffer[bptr] == boundary[bindex]) { + bptr++; + bindex++; + } else { + for (int i = 0; i < bindex; i++) + *uptr++ = boundary[i]; + *uptr++ = buffer[bptr++]; + bindex = 0; + } + } while(1); + printf("Done reading\n"); + printf("%s", upload_buffer); + if (!bindex || boundary[bindex]) + goto bad_request; + char *response = "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n\r\n" + " Upload OK" + "

    File uploaded successully

    "; + write(new_socket, response, strlen(response)); + goto done; + } + } + char *response = "HTTP/1.1 200 OK\r\n" + "Content-Type: "; write(new_socket, response, strlen(response)); - goto done; + + write(new_socket, mime, strlen(mime)); + response = "; charset=UTF-8\r\n\r\n"; + write(new_socket, response, strlen(response)); + if (filesize) + write(new_socket, buffer, filesize); + } else if (bytesRead == 0) { + printf("EOF\n"); + continue; + } else { + perror("Error reading buffer, nothing read...\n"); } - - char *mime =getMime(&buffer[5]); - printf("MIME type: %s\n", mime); - - fseek(inptr, 0L, SEEK_END); - int filesize = ftell(inptr); - printf("Filesize: %d\n", filesize); - rewind(inptr); - printf("Input file size: %ld\n", filesize); - if (filesize > BUFFER_SIZE) { - printf("File too large.\n"); - goto done; - } - size_t bytes_read = fread(buffer, 1, sizeof(buffer), inptr); - - printf("Bytes read: %ld\n", bytes_read); - - if (bytes_read != filesize) { - printf("Error reading input file.\n"); - goto done; - } - fclose(inptr); - char *response = "HTTP/1.1 200 OK\r\n" - "Content-Type: "; - write(new_socket, response, strlen(response)); - write(new_socket, mime, strlen(mime)); - response = "; charset=UTF-8\r\n\r\n"; - write(new_socket, response, strlen(response)); - - write(new_socket, buffer, filesize); - } - } else { - perror("Error reading buffer...\n"); - } - done: - close(new_socket); - } + close(new_socket); + continue; +bad_request: + printf("Bad request!\n"); + send_bad_request(new_socket); + close(new_socket); + } } -int main() { - struct Server server = serverConstructor(8080, launch); - server.launch(&server); - return 0; +int main() +{ + // Make sure we can handle writes to a dead client without a signal handler + signal(SIGPIPE, SIG_IGN); + + struct Server server = serverConstructor(8080, launch); + server.launch(&server); + + return 0; } diff --git a/tools/httpd_sim.h b/tools/httpd_sim.h index 1e4ccdb..412d2f8 100644 --- a/tools/httpd_sim.h +++ b/tools/httpd_sim.h @@ -3,7 +3,7 @@ #include -#define BUFFER_SIZE 16000 +#define BUFFER_SIZE 2400 struct Server { int domain; diff --git a/uip/Makefile b/uip/Makefile index 7a9ef28..17c232c 100644 --- a/uip/Makefile +++ b/uip/Makefile @@ -3,19 +3,24 @@ CC_FLAGS = -mmcs51 -I. -I../httpd ASM = sdas8051 AFLAGS= -plosgff +BUILDDIR = output/ + SRCS = timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c -OBJS = ${SRCS:.c=.rel} +OBJS = ${SRCS:%.c=$(BUILDDIR)%.rel} -all: $(OBJS) +all: create_build_dir $(OBJS) -%.rel: %.c - $(CC) $(CC_FLAGS) -c $< +create_build_dir: + mkdir -p $(BUILDDIR) -%.rel: %.asm +$(BUILDDIR)%.rel: %.c + $(CC) $(CC_FLAGS) -o $@ -c $< + +$(BUILDDIR)%.rel: $(BUILDDIR)%.asm ${ASM} ${AFLAGS} $^ clean: - rm *.ihx *.lk *.lst *.map *.mem *.rel *.rst *.sym *.bin + rm -r $(BUILDDIR) .PHONY: all clean