flashing works

This commit is contained in:
Polprzewodnikowy 2021-10-26 22:44:49 +02:00
parent 5ad902aa10
commit c4036a65cf
8 changed files with 117 additions and 11 deletions

View File

@ -19,7 +19,7 @@
#
# Quartus Prime
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
# Date created = 00:50:07 October 26, 2021
# Date created = 22:44:04 October 26, 2021
#
# -------------------------------------------------------------------------- #
#
@ -303,7 +303,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
# end DESIGN_PARTITION(Top)
# -------------------------

View File

@ -7,6 +7,7 @@ module n64_bootloader (
logic mem_request;
logic csr_ack;
logic data_ack;
logic write_ack;
logic data_busy;
logic mem_write;
logic [31:0] mem_address;
@ -29,6 +30,7 @@ module n64_bootloader (
always_ff @(posedge sys.clk) begin
csr_ack <= 1'b0;
write_ack <= 1'b0;
if (sys.reset) begin
state <= S_IDLE;
@ -61,7 +63,10 @@ module n64_bootloader (
if ((!mem_address[27] || source_request == T_N64) && !data_busy) begin
mem_request <= 1'b0;
end
if (csr_ack || data_ack) begin
if (!mem_address[27] && mem_write && !data_busy && !write_ack) begin
write_ack <= 1'b1;
end
if (csr_ack || data_ack || write_ack) begin
state <= S_IDLE;
end
end
@ -89,7 +94,7 @@ module n64_bootloader (
else bus.rdata = {data_rdata[7:0], data_rdata[15:8]};
end
flash.ack = source_request == T_CPU && (csr_ack || data_ack);
flash.ack = source_request == T_CPU && (csr_ack || data_ack || write_ack);
flash.rdata = 32'd0;
if (flash.ack) begin
flash.rdata = csr_or_data ? csr_rdata : data_rdata;

View File

@ -1,4 +1,5 @@
#include "cfg.h"
#include "flash.h"
#include "joybus.h"
#include "usb.h"
@ -26,6 +27,7 @@ enum cfg_id {
CFG_ID_SAVE_OFFEST,
CFG_ID_DD_OFFEST,
CFG_ID_SKIP_BOOTLOADER,
CFG_ID_FLASH_OPERATION,
};
enum save_type {
@ -132,6 +134,9 @@ void cfg_update (uint32_t *args) {
case CFG_ID_SKIP_BOOTLOADER:
change_scr_bits(CFG_SCR_SKIP_BOOTLOADER, args[1]);
break;
case CFG_ID_FLASH_OPERATION:
flash_program(args[1]);
break;
}
}
@ -167,6 +172,9 @@ void cfg_query (uint32_t *args) {
case CFG_ID_SKIP_BOOTLOADER:
args[1] = CFG->SCR & CFG_SCR_SKIP_BOOTLOADER;
break;
case CFG_ID_FLASH_OPERATION:
args[1] = flash_read(args[1]);
break;
}
}

60
sw/riscv/src/flash.c Normal file
View File

@ -0,0 +1,60 @@
#include "flash.h"
uint32_t flash_read (uint32_t sdram_offset) {
io32_t *flash = (io32_t *) (FLASH_BASE);
io32_t *sdram = (io32_t *) (SDRAM_BASE + sdram_offset);
for (size_t i = 0; i < FLASH_SIZE; i += 4) {
*sdram++ = *flash++;
}
return FLASH_SIZE;
}
void flash_program (uint32_t sdram_offset) {
uint32_t cr;
io32_t *flash = (io32_t *) (FLASH_BASE);
io32_t *sdram = (io32_t *) (SDRAM_BASE + sdram_offset);
cr = FLASH_CONFIG->CR;
for (size_t sector = 0; sector < FLASH_NUM_SECTORS; sector++) {
cr &= ~(1 << (FLASH_CR_WRITE_PROTECT_BIT + sector));
}
FLASH_CONFIG->CR = cr;
while ((FLASH_CONFIG->SR & FLASH_SR_STATUS_MASK) != FLASH_SR_STATUS_IDLE);
for (size_t sector = 0; sector < FLASH_NUM_SECTORS; sector++) {
cr = FLASH_CONFIG->CR;
cr &= ~(FLASH_CR_SECTOR_ERASE_MASK);
cr |= ((sector + 1) << FLASH_CR_SECTOR_ERASE_BIT);
FLASH_CONFIG->CR = cr;
while ((FLASH_CONFIG->SR & FLASH_SR_STATUS_MASK) == FLASH_SR_STATUS_BUSY_ERASE);
if (!(FLASH_CONFIG->SR & FLASH_SR_ERASE_SUCCESSFUL)) {
break;
}
}
if (FLASH_CONFIG->SR & FLASH_SR_ERASE_SUCCESSFUL) {
for (size_t word = 0; word < FLASH_SIZE; word += 4) {
*flash++ = *sdram++;
if (!(FLASH_CONFIG->SR & FLASH_SR_WRITE_SUCCESSFUL)) {
break;
}
}
}
cr = FLASH_CONFIG->CR;
cr |= FLASH_CR_SECTOR_ERASE_MASK;
for (size_t sector = 0; sector < FLASH_NUM_SECTORS; sector++) {
cr |= (1 << (FLASH_CR_WRITE_PROTECT_BIT + sector));
}
FLASH_CONFIG->CR = cr;
return;
}

12
sw/riscv/src/flash.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef FLASH_H__
#define FLASH_H__
#include "sys.h"
uint32_t flash_read (uint32_t sdram_offset);
void flash_program (uint32_t sdram_offset);
#endif

View File

@ -4,7 +4,7 @@
__attribute__ ((naked, section(".bootloader"))) void reset_handler (void) {
io32_t *ram = (io32_t *) &RAM;
io32_t *flash = (io32_t *) (FLASH_BASE + FLASH_IMAGE_OFFSET);
io32_t *flash = (io32_t *) (FLASH_BASE + FLASH_CPU_IMAGE_OFFSET);
for (int i = 0; i < RAM_SIZE; i += 4) {
*ram++ = *flash++;

View File

@ -157,16 +157,33 @@ typedef volatile struct joybus_regs {
#define FLASH_BASE (0xB0000000UL)
#define FLASH (*((io32_t *) FLASH_BASE))
#define FLASH_IMAGE_OFFSET (0x35800)
#define FLASH_CPU_IMAGE_OFFSET (0x35800)
#define FLASH_SIZE (0x39800)
#define FLASH_NUM_SECTORS (4)
typedef volatile struct flash_regs {
typedef volatile struct flash_config_regs {
io32_t SR;
io32_t CR;
} flash_regs_t;
} flash_config_regs_t;
#define FLASH_SCR_BASE (0xB8000000UL)
#define FLASH_SCR ((flash_regs_t *) FLASH_SCR_BASE)
#define FLASH_CONFIG_BASE (0xB8000000UL)
#define FLASH_CONFIG ((flash_config_regs_t *) FLASH_CONFIG_BASE)
#define FLASH_SR_STATUS_MASK (3 << 0)
#define FLASH_SR_STATUS_IDLE (0)
#define FLASH_SR_STATUS_BUSY_ERASE (1)
#define FLASH_SR_STATUS_BUSY_WRITE (2)
#define FLASH_SR_STATUS_BUSY_READ (3)
#define FLASH_SR_READ_SUCCESSFUL (1 << 2)
#define FLASH_SR_WRITE_SUCCESSFUL (1 << 3)
#define FLASH_SR_ERASE_SUCCESSFUL (1 << 4)
#define FLASH_SR_WRITE_PROTECT_BIT (5)
#define FLASH_CR_PAGE_ERASE_BIT (0)
#define FLASH_CR_SECTOR_ERASE_BIT (20)
#define FLASH_CR_SECTOR_ERASE_MASK (7 << FLASH_CR_SECTOR_ERASE_BIT)
#define FLASH_CR_WRITE_PROTECT_BIT (23)
void reset_handler (void);

View File

@ -77,6 +77,7 @@ struct process {
uint32_t args[2];
bool error;
bool dma_in_progress;
bool queried;
bool debug_rx_busy;
uint32_t debug_rx_address;
@ -173,6 +174,7 @@ void process_usb (void) {
p.counter = 0;
p.error = false;
p.dma_in_progress = false;
p.queried = false;
p.state = STATE_ARGS;
} else {
p.cmd = '!';
@ -199,7 +201,10 @@ void process_usb (void) {
break;
case 'Q':
if (!p.queried) {
cfg_query(p.args);
p.queried = true;
}
if (tx_word(p.args[1])) {
p.state = STATE_RESPONSE;
}