2024-08-06 22:28:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
// boot.c
|
|
|
|
//
|
|
|
|
// Written: Jacob Pease jacob.pease@okstate.edu 7/22/2024
|
|
|
|
//
|
|
|
|
// Purpose: Main bootloader entry point
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// A component of the Wally configurable RISC-V project.
|
|
|
|
//
|
|
|
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
|
|
|
//
|
|
|
|
// Licensed under the Solderpad Hardware License v 2.1 (the
|
|
|
|
// “License”); you may not use this file except in compliance with the
|
|
|
|
// License, or, at your option, the Apache License version 2.0. You
|
|
|
|
// may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// https://solderpad.org/licenses/SHL-2.1/
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, any work
|
|
|
|
// distributed under the License is distributed on an “AS IS” BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
|
|
// implied. See the License for the specific language governing
|
|
|
|
// permissions and limitations under the License.
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
2024-05-31 20:28:25 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include "boot.h"
|
|
|
|
#include "gpt.h"
|
2024-07-23 20:47:23 +00:00
|
|
|
#include "uart.h"
|
|
|
|
#include "spi.h"
|
|
|
|
#include "sd.h"
|
2024-08-02 20:19:52 +00:00
|
|
|
#include "time.h"
|
|
|
|
#include "riscv.h"
|
|
|
|
#include "fail.h"
|
2024-05-31 20:28:25 +00:00
|
|
|
|
2024-08-20 17:19:49 +00:00
|
|
|
|
|
|
|
// Maximum SD card clock frequency is either 20MHz or half of the
|
|
|
|
// system clock
|
|
|
|
|
|
|
|
/*
|
|
|
|
PSEUDOCODE:
|
|
|
|
transmit 8 dummy bytes
|
|
|
|
wait for receive fifo to get a byte.
|
|
|
|
- as soon as a byte is in the receive fifo
|
|
|
|
- process the byte and increment a byte counter.
|
|
|
|
when 8 bytes are transferred
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2024-07-23 19:18:42 +00:00
|
|
|
int disk_read(BYTE * buf, LBA_t sector, UINT count) {
|
2024-07-23 20:47:23 +00:00
|
|
|
uint64_t r;
|
2024-08-20 17:19:49 +00:00
|
|
|
UINT i, j;
|
2024-08-02 20:19:52 +00:00
|
|
|
volatile uint8_t *p = buf;
|
|
|
|
|
2024-08-20 17:19:49 +00:00
|
|
|
// Quarter of the Systemclock, divided by the number of bits in a block
|
|
|
|
// equals the number of blocks per second transferred.
|
|
|
|
UINT modulus = SDCCLOCK/(8*512);
|
2024-07-31 16:12:05 +00:00
|
|
|
|
2024-07-23 20:47:23 +00:00
|
|
|
uint8_t crc = 0;
|
|
|
|
crc = crc7(crc, 0x40 | SD_CMD_READ_BLOCK_MULTIPLE);
|
|
|
|
crc = crc7(crc, (sector >> 24) & 0xff);
|
|
|
|
crc = crc7(crc, (sector >> 16) & 0xff);
|
|
|
|
crc = crc7(crc, (sector >> 8) & 0xff);
|
|
|
|
crc = crc7(crc, sector & 0xff);
|
|
|
|
crc = crc | 1;
|
|
|
|
|
2024-07-31 16:12:05 +00:00
|
|
|
if ((r = sd_cmd(18, sector & 0xffffffff, crc) & 0xff) != 0x00) {
|
|
|
|
print_uart("disk_read: CMD18 failed. r = 0x");
|
|
|
|
print_uart_byte(r);
|
2024-07-25 18:05:57 +00:00
|
|
|
print_uart("\r\n");
|
2024-08-02 20:19:52 +00:00
|
|
|
fail();
|
|
|
|
// return -1;
|
2024-07-23 20:47:23 +00:00
|
|
|
}
|
|
|
|
|
2024-08-02 20:19:52 +00:00
|
|
|
print_uart("\r Blocks loaded: ");
|
|
|
|
print_uart("0");
|
|
|
|
print_uart("/");
|
|
|
|
print_uart_dec(count);
|
2024-07-31 16:12:05 +00:00
|
|
|
// write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_HOLD);
|
2024-07-23 21:33:49 +00:00
|
|
|
// Begin reading blocks
|
2024-07-23 20:47:23 +00:00
|
|
|
for (i = 0; i < count; i++) {
|
2024-07-23 21:33:49 +00:00
|
|
|
uint16_t crc, crc_exp;
|
2024-08-02 20:19:52 +00:00
|
|
|
uint64_t n = 0;
|
2024-07-31 16:12:05 +00:00
|
|
|
|
|
|
|
// Wait for data token
|
2024-08-02 20:19:52 +00:00
|
|
|
while((r = spi_dummy()) != SD_DATA_TOKEN);
|
2024-08-20 17:19:49 +00:00
|
|
|
|
2024-08-02 20:19:52 +00:00
|
|
|
crc = 0;
|
2024-08-20 19:40:50 +00:00
|
|
|
/* n = 512; */
|
2024-08-20 17:19:49 +00:00
|
|
|
/* do { */
|
2024-08-20 19:40:50 +00:00
|
|
|
/* uint8_t x = spi_dummy(); */
|
|
|
|
/* *p++ = x; */
|
|
|
|
/* crc = crc16(crc, x); */
|
|
|
|
/* } while (--n > 0); */
|
|
|
|
|
|
|
|
n = 512/8;
|
|
|
|
do {
|
|
|
|
// Send 8 dummy bytes (fifo should be empty)
|
|
|
|
for (j = 0; j < 8; j++) {
|
|
|
|
spi_sendbyte(0xff);
|
|
|
|
}
|
2024-08-20 17:19:49 +00:00
|
|
|
|
2024-08-20 19:40:50 +00:00
|
|
|
// Reset counter. Process bytes AS THEY COME IN.
|
|
|
|
for (j = 0; j < 8; j++) {
|
|
|
|
while (!(read_reg(SPI_IP) & 2)) {}
|
|
|
|
uint8_t x = spi_readbyte();
|
|
|
|
*p++ = x;
|
|
|
|
crc = crc16(crc, x);
|
|
|
|
}
|
|
|
|
} while(--n > 0);
|
2024-08-02 20:19:52 +00:00
|
|
|
|
2024-07-23 21:33:49 +00:00
|
|
|
// Read CRC16 and check
|
2024-08-02 20:19:52 +00:00
|
|
|
crc_exp = ((uint16_t)spi_dummy() << 8);
|
|
|
|
crc_exp |= spi_dummy();
|
2024-07-23 21:33:49 +00:00
|
|
|
|
|
|
|
if (crc != crc_exp) {
|
2024-07-31 16:12:05 +00:00
|
|
|
print_uart("Stinking CRC16 didn't match on block read.\r\n");
|
2024-07-23 22:00:32 +00:00
|
|
|
print_uart_int(i);
|
2024-07-23 21:33:49 +00:00
|
|
|
print_uart("\r\n");
|
2024-08-02 20:19:52 +00:00
|
|
|
//return -1;
|
|
|
|
fail();
|
2024-07-23 21:33:49 +00:00
|
|
|
}
|
2024-08-02 20:19:52 +00:00
|
|
|
|
|
|
|
if ( (i % modulus) == 0 ) {
|
|
|
|
print_uart("\r Blocks loaded: ");
|
|
|
|
print_uart_dec(i);
|
|
|
|
print_uart("/");
|
|
|
|
print_uart_dec(count);
|
|
|
|
}
|
|
|
|
|
2024-07-23 20:47:23 +00:00
|
|
|
}
|
2024-07-23 21:33:49 +00:00
|
|
|
|
|
|
|
sd_cmd(SD_CMD_STOP_TRANSMISSION, 0, 0x01);
|
2024-08-02 20:19:52 +00:00
|
|
|
|
|
|
|
print_uart("\r Blocks loaded: ");
|
|
|
|
print_uart_dec(count);
|
|
|
|
print_uart("/");
|
|
|
|
print_uart_dec(count);
|
|
|
|
print_uart("\r\n");
|
2024-07-23 21:33:49 +00:00
|
|
|
return 0;
|
2024-05-31 20:28:25 +00:00
|
|
|
}
|
|
|
|
|
2024-07-23 19:18:42 +00:00
|
|
|
// copyFlash: --------------------------------------------------------
|
|
|
|
// A lot happens in this function:
|
|
|
|
// * The Wally banner is printed
|
|
|
|
// * The peripherals are initialized
|
2024-05-31 20:28:25 +00:00
|
|
|
void copyFlash(QWORD address, QWORD * Dst, DWORD numBlocks) {
|
|
|
|
int ret = 0;
|
|
|
|
|
2024-07-23 19:18:42 +00:00
|
|
|
// Initialize UART for messages
|
2024-07-25 03:43:47 +00:00
|
|
|
init_uart(20000000, 115200);
|
2024-08-02 20:19:52 +00:00
|
|
|
|
2024-07-23 19:18:42 +00:00
|
|
|
// Print the wally banner
|
|
|
|
print_uart(BANNER);
|
2024-05-31 20:28:25 +00:00
|
|
|
|
2024-07-31 16:12:05 +00:00
|
|
|
/* print_uart("System clock speed: "); */
|
|
|
|
/* print_uart_dec(SYSTEMCLOCK); */
|
|
|
|
/* print_uart("\r\n"); */
|
|
|
|
|
2024-07-23 20:47:23 +00:00
|
|
|
// Intialize the SD card
|
2024-08-20 17:19:49 +00:00
|
|
|
init_sd(SYSTEMCLOCK, SDCCLOCK);
|
2024-05-31 20:28:25 +00:00
|
|
|
|
2024-07-23 22:00:32 +00:00
|
|
|
ret = gpt_load_partitions();
|
2024-05-31 20:28:25 +00:00
|
|
|
}
|