Commit 24c9464c authored by Pavel Pisa's avatar Pavel Pisa

Copy templates from B35APO teachers repository to students accessible one.

The Computer Architectures course pages

  https://cw.fel.cvut.cz/wiki/courses/b35apo/startSigned-off-by: Pavel Pisa's avatarPavel Pisa <pisa@cmp.felk.cvut.cz>
parents
## CTU FEE Computer Architectures Course Support Materials for Students
The course pages: [https://cw.fel.cvut.cz/wiki/courses/b35apo/start](https://cw.fel.cvut.cz/wiki/courses/b35apo/start)
The directory `seminaries` provides templates and test applications
for seminaries. The can be modified to experiment and even
archive modifications. But the work which is intended to be shared
with your tutor should be placed into directory `work`.
CC = arm-linux-gnueabihf-gcc
CXX = arm-linux-gnueabihf-g++
CPPFLAGS = -I .
CFLAGS =-g -std=gnu99 -O1 -Wall
CXXFLAGS = -g -std=gnu++11 -O1 -Wall
LDFLAGS = -lrt -lpthread
SOURCES = mzapo_binrep.c
TARGET_EXE = mzapo_binrep
#TARGET_IP ?= 192.168.202.127
ifeq ($(TARGET_IP)$(filter run,$(MAKECMDGOALS)),run)
$(warning The target IP address is not set)
$(warning Run as "TARGET_IP=192.168.202.xxx make run" or modify Makefile)
TARGET_IP ?= 192.168.202.xxx
endif
TARGET_DIR ?= /tmp/$(shell whoami)
TARGET_USER ?= root
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
#$(warning OBJECTS=$(OBJECTS))
ifeq ($(filter %.cpp,$(SOURCES)),)
LINKER = $(CC)
LDFLAGS += $(CFLAGS) $(CPPFLAGS)
else
LINKER = $(CXX)
LDFLAGS += $(CXXFLAGS) $(CPPFLAGS)
endif
%.o:%.c
$(CC) $(CFLAGS) -c $<
%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $<
all: $(TARGET_EXE)
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $@
.PHONY : dep all run
dep: depend
depend: $(SOURCES) *.h
echo '# autogenerated dependencies' > depend
ifneq ($(filter %.c,$(SOURCES)),)
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
>> depend
endif
clean:
rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) connect.gdb depend
copy-executable: $(TARGET_EXE)
ssh -t $(TARGET_USER)@$(TARGET_IP) killall gdbserver 1>/dev/null 2>/dev/null || true
ssh $(TARGET_USER)@$(TARGET_IP) mkdir -p $(TARGET_DIR)
scp $(TARGET_EXE) $(TARGET_USER)@$(TARGET_IP):$(TARGET_DIR)/$(TARGET_EXE)
run: copy-executable $(TARGET_EXE)
ssh -t $(TARGET_USER)@$(TARGET_IP) $(TARGET_DIR)/$(TARGET_EXE)
debug: copy-executable $(TARGET_EXE)
xterm -e ssh -t $(TARGET_USER)@$(TARGET_IP) gdbserver :12345 $(TARGET_DIR)/$(TARGET_EXE) &
sleep 2
echo >connect.gdb "target extended-remote $(TARGET_IP):12345"
echo >>connect.gdb "b main"
echo >>connect.gdb "c"
ddd --debugger gdb-multiarch -x connect.gdb $(TARGET_EXE)
-include depend
/*******************************************************************
Simple program to demostrate binary reprezentation on MicroZed
based MZ_APO board designed by Petr Porazil at PiKRON
mzapo_binrep.c - main and only file
(C) Copyright 2004 - 2017 by Pavel Pisa
e-mail: pisa@cmp.felk.cvut.cz
homepage: http://cmp.felk.cvut.cz/~pisa
work: http://www.pikron.com/
license: any combination GPL, LGPL, MPL or BSD licenses
*******************************************************************/
#define _POSIX_C_SOURCE 200112L
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#include <string.h>
#include <byteswap.h>
#include <getopt.h>
#include <inttypes.h>
#include <time.h>
char *memdev="/dev/mem";
/*
* Next macros provides location of knobs and LEDs peripherals
* implemented in MZ_APO FPGA design.
*
* The complete list of peripheral implemented in the design
* can be found on the page
* https://cw.fel.cvut.cz/wiki/courses/b35apo/documentation/mz_apo/start
*/
/*
* Base address of the region used for mapping of the knobs and LEDs
* peripherals in the ARM Cortex-A9 physical memory address space.
*/
#define SPILED_REG_BASE_PHYS 0x43c40000
/* Valid address range for the region */
#define SPILED_REG_SIZE 0x00004000
/*
* Byte offset of the register which controls individual LEDs
* in the row of 32 yellow LEDs. When the corresponding bit
* is set (value 1) then the LED is lit.
*/
#define SPILED_REG_LED_LINE_o 0x004
/*
* The register to control 8 bit RGB components of brightness
* of the first RGB LED
*/
#define SPILED_REG_LED_RGB1_o 0x010
/*
* The register to control 8 bit RGB components of brightness
* of the second RGB LED
*/
#define SPILED_REG_LED_RGB2_o 0x014
/*
* The register which combines direct write to RGB signals
* of the RGB LEDs, write to the keyboard scan register
* and control of the two additional individual LEDs.
* The direct write to RGB signals is orred with PWM
* signal generated according to the values in previous
* registers.
*/
#define SPILED_REG_LED_KBDWR_DIRECT_o 0x018
/*
* Register providing access to unfiltered encoder channels
* and keyboard return signals.
*/
#define SPILED_REG_KBDRD_KNOBS_DIRECT_o 0x020
/*
* The register representing knobs positions as three
* 8-bit values where each value is incremented
* and decremented by the knob relative turning.
*/
#define SPILED_REG_KNOBS_8BIT_o 0x024
/*
* The support function which returns pointer to the virtual
* address at which starts remapped physical region in the
* process virtual memory space.
*/
void *map_phys_address(off_t region_base, size_t region_size, int opt_cached)
{
unsigned long mem_window_size;
unsigned long pagesize;
unsigned char *mm;
unsigned char *mem;
int fd;
/*
* Open a device ("/dev/mem") representing physical address space
* in POSIX systems
*/
fd = open(memdev, O_RDWR | (!opt_cached? O_SYNC: 0));
if (fd < 0) {
fprintf(stderr, "cannot open %s\n", memdev);
return NULL;
}
/*
* The virtual to physical address mapping translation granularity
* corresponds to memory page size. This call obtains the page
* size used by running operating system at given CPU architecture.
* 4kB are used by Linux running on ARM, ARM64, x86 and x86_64 systems.
*/
pagesize=sysconf(_SC_PAGESIZE);
/*
* Extend physical region start address and size to page size boundaries
* to cover complete requested region.
*/
mem_window_size = ((region_base & (pagesize-1)) + region_size + pagesize-1) & ~(pagesize-1);
/*
* Map file (in our case physical memory) range at specified offset
* to virtual memory ragion/area (see VMA Linux kernel structures)
* of the process.
*/
mm = mmap(NULL, mem_window_size, PROT_WRITE|PROT_READ,
MAP_SHARED, fd, region_base & ~(pagesize-1));
/* Report failure if the mmap is not allowed for given file or its region */
if (mm == MAP_FAILED) {
fprintf(stderr,"mmap error\n");
return NULL;
}
/*
* Add offset in the page to the returned pointer for non-page-aligned
* requests.
*/
mem = mm + (region_base & (pagesize-1));
return mem;
}
/*
* The main entry into example program
*/
int main(int argc, char *argv[])
{
unsigned char *mem_base;
/*
* Setup memory mapping which provides access to the peripheral
* registers region of RGB LEDs, knobs and line of yellow LEDs.
*/
mem_base = map_phys_address(SPILED_REG_BASE_PHYS, SPILED_REG_SIZE, 0);
/* If mapping fails exit with error code */
if (mem_base == NULL)
exit(1);
while (1) {
uint32_t rgb_knobs_value;
int int_val;
unsigned int uint_val;
/* Initialize structure to 0 seconds and 200 milliseconds */
struct timespec loop_delay = {.tv_sec = 0, .tv_nsec = 200 * 1000 * 1000};
/*
* Access register holding 8 bit relative knobs position
* The type "(volatile uint32_t*)" casts address obtained
* as a sum of base address and register offset to the
* pointer type which target in memory type is 32-bit unsigned
* integer. The "volatile" keyword ensures that compiler
* cannot reuse previously read value of the location.
*/
rgb_knobs_value = *(volatile uint32_t*)(mem_base + SPILED_REG_KNOBS_8BIT_o);
/* Store the read value to the register controlling individual LEDs */
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = rgb_knobs_value;
/*
* Store RGB knobs values to the corersponding components controlling
* a color/brightness of the RGB LEDs
*/
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB1_o) = rgb_knobs_value;
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB2_o) = rgb_knobs_value;
/* Assign value read from knobs to the basic signed and unsigned types */
int_val = rgb_knobs_value;
uint_val = rgb_knobs_value;
/* Print values */
printf("int %10d uint 0x%08x\n", int_val, uint_val);
/*
* Wait for time specified by "loop_delay" variable.
* Use monotonic clocks as time reference to ensure
* that wait interval is not prolonged or shortened
* due to real time adjustment.
*/
clock_nanosleep(CLOCK_MONOTONIC, 0, &loop_delay, NULL);
}
return 0;
}
CC=gcc
#CC=arm-linux-gnueabihf-gcc
CFLAGS=-g -std=c99 -pedantic -Wall
LDFLAGS=-lrt -lpthread
%.o:%.c
$(CC) $(CFLAGS) -c $<
all: print_binrep
print_binrep: print_binrep.o
$(CC) $(CFLAGS) $(LDFLAGS) -L. $^ -o $@
.PHONY : depend dep all
dep:
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M *.c \
> depend
depend:
@touch depend
clean:
rm -f *.o *.a print_binrep depend
-include depend
/* Simple program to examine how are different data types encoded in memory */
#include <stdio.h>
/*
* The macro determines size of given variable and then
* prints individual bytes of the value representation
*/
#define PRINT_MEM(a) print_mem((unsigned char*)&(a), sizeof(a))
void print_mem(unsigned char *ptr, int size) {
int i;
printf("address = 0x%08lx\n", (long unsigned int)ptr);
for (i = 0; i < size; i++) {
printf("0x%02x ", *(ptr+i));
}
printf("\n");
}
int main() {
/* try for more types: long, float, double, pointer */
unsigned int unsig = 5;
int sig = -5;
/* Read GNU C Library manual for conversion syntax for other types */
/* https://www.gnu.org/software/libc/manual/html_node/Formatted-Output.html */
printf("value = %d\n", unsig);
PRINT_MEM(unsig);
printf("\nvalue = %d\n", sig);
PRINT_MEM(sig);
return 0;
}
#!/usr/bin/python3
import struct
a = 0x5f
print("{0:08b}".format(a))
s = ''
binord = 7
while binord >= 0:
if a & (1 << binord):
s += '1'
else:
s += '0'
binord -= 1
print(s)
f = 12.3456
g = 1024.0
buf = struct.pack('<ff', g, f)
print(buf)
print (["{0:02x}".format(b) for b in buf])
(u32_f, u32_g) = struct.unpack('<II', buf)
print(" f = {0:08x}".format(u32_f))
print(" g = {0:08x}".format(u32_g))
ARCH=mips-elf
#ARCH=mips-linux-gnu
SOURCES = crt0local.S qtmips_binrep.c
TARGET_EXE = qtmips_binrep
CC=$(ARCH)-gcc
CXX=$(ARCH)-g++
AS=$(ARCH)-as
LD=$(ARCH)-ld
OBJCOPY=$(ARCH)-objcopy
#ARCHFLAGS += -march=mips3
ARCHFLAGS += -fno-lto
#ARCHFLAGS += -mno-shared
CFLAGS += -ggdb -Os -Wall
CXXFLAGS+= -ggdb -Os -Wall
AFLAGS += -ggdb
LDFLAGS += -ggdb
LDFLAGS += -nostartfiles
LDFLAGS += -static
#LDFLAGS += -specs=/opt/musl/mips-linux-gnu/lib/musl-gcc.specs
CFLAGS += $(ARCHFLAGS)
CXXFLAGS+= $(ARCHFLAGS)
AFLAGS += $(ARCHFLAGS)
LDFLAGS += $(ARCHFLAGS)
OBJECTS += $(filter %.o,$(SOURCES:%.S=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
all : default
.PHONY : default clean dep all
%.o:%.S
$(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $@
%.o:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
%.o:%.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
%.s:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -S $< -o $@
default : $(TARGET_EXE)
$(TARGET_EXE) : $(OBJECTS)
$(CC) $(LDFLAGS) $^ -o $@
dep: depend
depend: $(SOURCES) $(glob *.h)
echo '# autogenerated dependencies' > depend
ifneq ($(filter %.S,$(SOURCES)),)
$(CC) -D__ASSEMBLY__ $(AFLAGS) -w -E -M $(filter %.S,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.c,$(SOURCES)),)
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
>> depend
endif
clean:
rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) depend
#mips-elf-objdump --source -M no-aliases,reg-names=numeric qtmips_binrep
-include depend
/* minimal replacement of crt0.o which is else provided by C library */
.globl main
.globl _start
.globl __start
.set noat
.set noreorder
.ent _start
.text
__start:
_start:
#if defined(__PIC__) || defined(__pic__)
bal next
nop
next:
.set noreorder
.cpload $31
.set reorder
#else
la $gp, _gp
#endif
addi $a0, $zero, 0
addi $a1, $zero, 0
jal main
nop
quit:
addi $a0, $zero, 0
addi $v0, $zero, 4001 /* SYS_exit */
syscall
loop: break
beq $zero, $zero, loop
nop
.end _start
/*******************************************************************
Simple program to demostrate binary reprezentation
on QtMips emulator developed by Karel Koci and Pavel Pisa.
qrmips_binrep.c - main and only file
(C) Copyright 2004 - 2019 by Pavel Pisa
e-mail: pisa@cmp.felk.cvut.cz
homepage: http://cmp.felk.cvut.cz/~pisa
work: http://www.pikron.com/
license: any combination GPL, LGPL, MPL or BSD licenses
*******************************************************************/
#define _POSIX_C_SOURCE 200112L
#include <stdint.h>
/*
* Next macros provides location of knobs and LEDs peripherals
* implemented on QtMips simulator.
*
* More information can be found on page
* https://github.com/ppisa/QtMips
*/
/*
* Base address of the region where simple serial port (UART)
* implementation is mapped in emulated MIPS address space
*/
#define SERIAL_PORT_BASE 0xffffc000
/*
* Byte offset of the 32-bit transition status register
* of the serial port
*/
#define SERP_TX_ST_REG_o 0x08
/*
* Mask of the bit which inform that peripheral is ready to accept
* next character to send. If it is zero, then peripheral is
* busy by sending of previous character.
*/
#define SERP_TX_ST_REG_READY_m 0x1
/*
* Byte offset of the UART transmit register.
* When the 32-bit word is written the least-significant (LSB)
* eight bits are send to the terminal.
*/
#define SERP_TX_DATA_REG_o 0x0c
/*
* Base address of the region where knobs and LEDs peripherals
* are mapped in the emulated MIPS physical memory address space.
*/
#define SPILED_REG_BASE 0xffffc100
/* Valid address range for the region */
#define SPILED_REG_SIZE 0x00000100
/*
* Byte offset of the register which controls individual LEDs
* in the row of 32 yellow LEDs. When the corresponding bit
* is set (value 1) then the LED is lit.
*/
#define SPILED_REG_LED_LINE_o 0x004
/*
* The register to control 8 bit RGB components of brightness
* of the first RGB LED
*/
#define SPILED_REG_LED_RGB1_o 0x010
/*
* The register to control 8 bit RGB components of brightness
* of the second RGB LED
*/
#define SPILED_REG_LED_RGB2_o 0x014
/*
* The register which combines direct write to RGB signals
* of the RGB LEDs, write to the keyboard scan register
* and control of the two additional individual LEDs.
* The direct write to RGB signals is orred with PWM
* signal generated according to the values in previous
* registers.
*/
#define SPILED_REG_LED_KBDWR_DIRECT_o 0x018
/*
* Register providing access to unfiltered encoder channels
* and keyboard return signals.
*/
#define SPILED_REG_KBDRD_KNOBS_DIRECT_o 0x020
/*
* The register representing knobs positions as three
* 8-bit values where each value is incremented
* and decremented by the knob relative turning.
*/
#define SPILED_REG_KNOBS_8BIT_o 0x024
static inline void serp_write_reg(uint32_t base, uint32_t reg, uint32_t val)
{
*(volatile uint32_t *)(base + reg) = val;
}
static inline uint32_t serp_read_reg(uint32_t base, uint32_t reg)