initial commit
This commit is contained in:
		
				commit
				
					
						c8a56a78ec
					
				
			
		
					 9 changed files with 221 additions and 0 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | |||
| .vscode/ | ||||
| build/ | ||||
							
								
								
									
										28
									
								
								Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| CC := gcc | ||||
| CFLAGS := -Wall -Wextra -std=gnu23 -I include -O3 | ||||
| SRC_DIR := src | ||||
| BUILD_DIR := build | ||||
| PROGRAM_NAME := criscv | ||||
| 
 | ||||
| # Find all .c files in src directory
 | ||||
| SRCS := $(wildcard $(SRC_DIR)/*.c) | ||||
| # Generate corresponding .o file names in obj directory
 | ||||
| OBJS := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/obj/%.o,$(SRCS)) | ||||
| # Name of the final executable
 | ||||
| TARGET := $(BUILD_DIR)/$(PROGRAM_NAME) | ||||
| 
 | ||||
| .PHONY: all clean | ||||
| 
 | ||||
| all: $(TARGET) | ||||
| 
 | ||||
| $(TARGET): $(OBJS) | $(BUILD_DIR) | ||||
| 	$(CC) $(CFLAGS) $^ -o $@ | ||||
| 
 | ||||
| $(BUILD_DIR)/obj/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)/obj | ||||
| 	$(CC) $(CFLAGS) -c $< -o $@ | ||||
| 
 | ||||
| $(BUILD_DIR) $(BUILD_DIR)/obj: | ||||
| 	mkdir -p $@ | ||||
| 
 | ||||
| clean: | ||||
| 	rm -rf $(BUILD_DIR) | ||||
							
								
								
									
										12
									
								
								include/address_space.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								include/address_space.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| #include <stdint.h> | ||||
| 
 | ||||
| struct AddressSpace_s { | ||||
|     uint8_t *rom; | ||||
|     uint32_t romSize; | ||||
|     uint8_t *ram; | ||||
|     uint32_t ramSize; | ||||
| }; | ||||
| 
 | ||||
| typedef struct AddressSpace_s AddressSpace; | ||||
| 
 | ||||
| AddressSpace create_address_space(int romSize, int ramSize); | ||||
							
								
								
									
										12
									
								
								include/cpu.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								include/cpu.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| #include "address_space.h" | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| struct CPU_s { | ||||
|     uint32_t registers[32]; | ||||
|     uint32_t programCounter; | ||||
|     AddressSpace *addressSpace; | ||||
| }; | ||||
| 
 | ||||
| typedef struct CPU_s CPU; | ||||
| 
 | ||||
| CPU create_cpu(AddressSpace *addressSpace); | ||||
							
								
								
									
										3
									
								
								include/program_loader.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								include/program_loader.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| #include "address_space.h" | ||||
| 
 | ||||
| int load_to_rom(const char filename[], AddressSpace *addressSpace); | ||||
							
								
								
									
										87
									
								
								src/address_space.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/address_space.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,87 @@ | |||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| struct AddressSpace_s { | ||||
|     // A pointer to a ROM array. The array can vary in length.
 | ||||
|     uint8_t *rom; | ||||
|     // The size of ROM.
 | ||||
|     uint32_t romSize; | ||||
| 
 | ||||
|     // A pointer to a RAM array. The array can vary in length.
 | ||||
|     uint8_t *ram; | ||||
|     // The size of RAM.
 | ||||
|     uint32_t ramSize; | ||||
| }; | ||||
| 
 | ||||
| typedef struct AddressSpace_s AddressSpace; | ||||
| 
 | ||||
| 
 | ||||
| AddressSpace create_address_space(int romSize, int ramSize) { | ||||
|     uint8_t rom[romSize]; | ||||
|     uint8_t ram[ramSize]; | ||||
| 
 | ||||
|     AddressSpace addressSpace = { rom, romSize, ram, ramSize }; | ||||
| 
 | ||||
|     return addressSpace; | ||||
| } | ||||
| 
 | ||||
| int read_address_space(const AddressSpace *addressSpace, uint32_t address, const int n, uint8_t *dest) { | ||||
|     uint32_t romSize = addressSpace->romSize; | ||||
|     uint32_t ramSize = addressSpace->ramSize; | ||||
| 
 | ||||
|     if (address < romSize) { | ||||
|         if (address + n < romSize) { | ||||
|             fprintf(stderr, "Reading %d bytes from %d will exceed ROM address space of %d\n", n, address, romSize); // TODO maybe move to perror
 | ||||
|             return 1; | ||||
|         } else { | ||||
|             for (int i=0; i<n; i++) { | ||||
|                 dest[i] = addressSpace->rom[address + i]; | ||||
|             } | ||||
|         } | ||||
|     } else if (address < romSize + ramSize) { | ||||
|         if (address + n < romSize + ramSize) { | ||||
|             fprintf(stderr, "Reading %d bytes from %d (total %d) will exceed RAM address space of %d (total %d)\n", n, address, address + romSize, ramSize, romSize + ramSize); | ||||
|             return 1; | ||||
|         } else { | ||||
|             address -= romSize; | ||||
|             for (int i=0; i<n; i++) { | ||||
|                 dest[i] = addressSpace->ram[address + i]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } else { | ||||
|         // TODO IO
 | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int write_address_space(const AddressSpace *addressSpace, uint32_t address, const int n, uint8_t *src) { | ||||
|     uint32_t romSize = addressSpace->romSize; | ||||
|     uint32_t ramSize = addressSpace->ramSize; | ||||
| 
 | ||||
|     if (address < romSize) { | ||||
|         if (address + n < romSize) { | ||||
|             fprintf(stderr, "Writing %d bytes to %d will exceed ROM address space of %d\n", n, address, romSize); | ||||
|             return 1; | ||||
|         } else { | ||||
|             for (int i=0; i<n; i++) { | ||||
|                 addressSpace->rom[address + i] = src[i]; | ||||
|             } | ||||
|         } | ||||
|     } else if (address < romSize + ramSize) { | ||||
|         if (address + n < romSize + ramSize) { | ||||
|             fprintf(stderr, "Writing %d bytes to %d (total %d) will exceed RAM address space of %d (total %d)\n", n, address, address + romSize, ramSize, romSize + ramSize); | ||||
|             return 1; | ||||
|         } else { | ||||
|             address -= romSize; | ||||
|             for (int i=0; i<n; i++) { | ||||
|                 addressSpace->ram[address + i] = src[i]; | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         // TODO IO
 | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/cpu.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/cpu.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| #include <stdint.h> | ||||
| #include "address_space.h" | ||||
| 
 | ||||
| struct CPU_s { | ||||
|     // [32] of 32bit (uint32_t) registers 
 | ||||
|     uint32_t registers[32]; | ||||
| 
 | ||||
|     // Points to the byte of current instruction. Also known as pc
 | ||||
|     uint32_t programCounter; | ||||
| 
 | ||||
|     // The address space
 | ||||
|     AddressSpace *addressSpace; | ||||
| } cpu_default = { | ||||
|     .registers = {0}, | ||||
|     .programCounter = 0 | ||||
| }; | ||||
| 
 | ||||
| typedef struct CPU_s CPU; | ||||
| 
 | ||||
| 
 | ||||
| CPU create_cpu(AddressSpace *addressSpace) { | ||||
|     CPU cpu = cpu_default; | ||||
|     cpu.addressSpace = addressSpace; | ||||
|      | ||||
|     return cpu; | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/main.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "program_loader.h" | ||||
| #include "cpu.h" | ||||
| 
 | ||||
| int main(int argc, char *argv[]) { | ||||
|     if (argc == 0) { | ||||
|         fprintf(stderr, "Usage: criscv <binary program>\n"); | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     AddressSpace addressSpace = create_address_space(1024, 1024); | ||||
|     printf("Address space: %dB ROM, %dB RAM\n", addressSpace.romSize, addressSpace.ramSize); | ||||
| 
 | ||||
|     if (load_to_rom(argv[1], &addressSpace) != 0) { | ||||
|         fprintf(stderr, "Error loading program\n"); | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     CPU cpu = create_cpu(&addressSpace); | ||||
| 
 | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										27
									
								
								src/program_loader.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/program_loader.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| #include <stdio.h> | ||||
| #include "address_space.h" | ||||
| 
 | ||||
| int load_to_rom(const char filename[], AddressSpace *addressSpace) { | ||||
|     FILE *file = fopen(filename, "rb"); | ||||
|      | ||||
|     if (file == NULL) { | ||||
|         perror("Error opening file\n"); | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     int romSize = addressSpace->romSize; | ||||
|     uint8_t buffer[romSize]; | ||||
|     fread(buffer, 1, romSize, file); | ||||
| 
 | ||||
|     fseek(file, 0, SEEK_END); | ||||
|     int fileLen = ftell(file); | ||||
| 
 | ||||
|     if (fileLen > romSize) { | ||||
|         fprintf(stderr, "File has %d bytes, and won't fit in ROM of capacity %d bytes\n", fileLen, romSize); | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     addressSpace->rom = buffer; | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Minecon724
				Minecon724