提交 f2318967 编写于 作者: Y Yifan Wu

Remove K210 support.

上级 e2709203
......@@ -14,17 +14,10 @@ bitflags = "1.2.1"
xmas-elf = "0.7.0"
volatile = "0.3"
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" }
k210-pac = { git = "https://github.com/wyfcyx/k210-pac" }
k210-hal = { git = "https://github.com/wyfcyx/k210-hal" }
k210-soc = { git = "https://github.com/wyfcyx/k210-soc" }
easy-fs = { path = "../easy-fs" }
virtio-input-decoder = "0.1.4"
embedded-graphics = "0.7.1"
tinybmp = "0.3.1"
[features]
board_qemu = []
board_k210 = []
[profile.release]
debug = true
......@@ -5,14 +5,12 @@ KERNEL_ELF := target/$(TARGET)/$(MODE)/os
KERNEL_BIN := $(KERNEL_ELF).bin
DISASM_TMP := target/$(TARGET)/$(MODE)/asm
FS_IMG := ../user/target/$(TARGET)/$(MODE)/fs.img
SDCARD := /dev/sdb
APPS := ../user/src/bin/*
# BOARD
BOARD ?= qemu
BOARD := qemu
SBI ?= rustsbi
BOOTLOADER := ../bootloader/$(SBI)-$(BOARD).bin
K210_BOOTLOADER_SIZE := 131072
# Building mode argument
ifeq ($(MODE), release)
......@@ -20,15 +18,7 @@ ifeq ($(MODE), release)
endif
# KERNEL ENTRY
ifeq ($(BOARD), qemu)
KERNEL_ENTRY_PA := 0x80200000
else ifeq ($(BOARD), k210)
KERNEL_ENTRY_PA := 0x80020000
endif
# Run K210
K210-SERIALPORT = /dev/ttyUSB0
K210-BURNER = ../tools/kflash.py
KERNEL_ENTRY_PA := 0x80200000
# Binutils
OBJDUMP := rust-objdump --arch-name=riscv64
......@@ -40,14 +30,7 @@ DISASM ?= -x
# Run usertests or usershell
TEST ?=
build: env switch-check $(KERNEL_BIN) fs-img
switch-check:
ifeq ($(BOARD), qemu)
(which last-qemu) || (rm -f last-k210 && touch last-qemu && make clean)
else ifeq ($(BOARD), k210)
(which last-k210) || (rm -f last-qemu && touch last-k210 && make clean)
endif
build: env $(KERNEL_BIN) fs-img
env:
(rustup target list | grep "riscv64gc-unknown-none-elf (installed)") || rustup target add $(TARGET)
......@@ -55,11 +38,6 @@ env:
rustup component add rust-src
rustup component add llvm-tools-preview
sdcard: fs-img
@echo "Are you sure write to $(SDCARD) ? [y/N] " && read ans && [ $${ans:-N} = y ]
@sudo dd if=/dev/zero of=$(SDCARD) bs=1048576 count=32
@sudo dd if=$(FS_IMG) of=$(SDCARD)
$(KERNEL_BIN): kernel
@$(OBJCOPY) $(KERNEL_ELF) --strip-all -O binary $@
......@@ -73,7 +51,7 @@ $(APPS):
kernel:
@echo Platform: $(BOARD)
@cp src/linker-$(BOARD).ld src/linker.ld
@cargo build --release --features "board_$(BOARD)"
@cargo build --release
@rm src/linker.ld
clean:
......@@ -105,7 +83,6 @@ ifeq ($(BOARD),qemu)
endif
run-inner: build
ifeq ($(BOARD),qemu)
@qemu-system-riscv64 \
-M 128m \
-machine virt \
......@@ -118,15 +95,6 @@ ifeq ($(BOARD),qemu)
-device virtio-keyboard-device \
-device virtio-mouse-device \
-serial stdio
else
(which $(K210-BURNER)) || (cd .. && git clone https://github.com/sipeed/kflash.py.git && mv kflash.py tools)
@cp $(BOOTLOADER) $(BOOTLOADER).copy
@dd if=$(KERNEL_BIN) of=$(BOOTLOADER).copy bs=$(K210_BOOTLOADER_SIZE) seek=1
@mv $(BOOTLOADER).copy $(KERNEL_BIN)
@sudo chmod 777 $(K210-SERIALPORT)
python3 $(K210-BURNER) -p $(K210-SERIALPORT) -b 1500000 $(KERNEL_BIN)
python3 -m serial.tools.miniterm --eol LF --dtr 0 --rts 0 --filter direct $(K210-SERIALPORT) 115200
endif
debug: build
@tmux new-session -d \
......@@ -141,4 +109,4 @@ gdbserver: build
gdbclient:
@riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'
.PHONY: build env kernel clean disasm disasm-vim run-inner switch-check fs-img gdbserver gdbclient
.PHONY: build env kernel clean disasm disasm-vim run-inner fs-img gdbserver gdbclient
pub const CLOCK_FREQ: usize = 403000000 / 62;
pub const MMIO: &[(usize, usize)] = &[
// we don't need clint in S priv when running
// we only need claim/complete for target0 after initializing
(0x0C00_0000, 0x3000), /* PLIC */
(0x0C20_0000, 0x1000), /* PLIC */
(0x3800_0000, 0x1000), /* UARTHS */
(0x3800_1000, 0x1000), /* GPIOHS */
(0x5020_0000, 0x1000), /* GPIO */
(0x5024_0000, 0x1000), /* SPI_SLAVE */
(0x502B_0000, 0x1000), /* FPIOA */
(0x502D_0000, 0x1000), /* TIMER0 */
(0x502E_0000, 0x1000), /* TIMER1 */
(0x502F_0000, 0x1000), /* TIMER2 */
(0x5044_0000, 0x1000), /* SYSCTL */
(0x5200_0000, 0x1000), /* SPI0 */
(0x5300_0000, 0x1000), /* SPI1 */
(0x5400_0000, 0x1000), /* SPI2 */
];
pub type BlockDeviceImpl = crate::drivers::block::SDCardWrapper;
pub fn device_init() {
unimplemented!();
}
pub fn irq_handler() {
unimplemented!();
}
use crate::drivers::chardev::CharDevice;
#[cfg(feature = "board_qemu")]
use crate::drivers::chardev::UART;
#[cfg(feature = "board_k210")]
use crate::sbi::console_putchar;
use core::fmt::{self, Write};
struct Stdout;
......@@ -10,10 +7,7 @@ struct Stdout;
impl Write for Stdout {
fn write_str(&mut self, s: &str) -> fmt::Result {
for c in s.chars() {
#[cfg(feature = "board_qemu")]
UART.write(c as u8);
#[cfg(feature = "board_k210")]
console_putchar(c as usize);
}
Ok(())
}
......
mod sdcard;
mod virtio_blk;
pub use sdcard::SDCardWrapper;
pub use virtio_blk::VirtIOBlock;
use crate::board::BlockDeviceImpl;
......
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(unused)]
use super::BlockDevice;
use crate::sync::UPIntrFreeCell;
use core::convert::TryInto;
use k210_hal::prelude::*;
use k210_pac::{Peripherals, SPI0};
use k210_soc::{
fpioa::{self, io},
//dmac::{dma_channel, DMAC, DMACExt},
gpio,
gpiohs,
sleep::usleep,
spi::{aitm, frame_format, tmod, work_mode, SPIExt, SPIImpl, SPI},
sysctl,
};
use lazy_static::*;
pub struct SDCard<SPI> {
spi: SPI,
spi_cs: u32,
cs_gpionum: u8,
//dmac: &'a DMAC,
//channel: dma_channel,
}
/*
* Start Data tokens:
* Tokens (necessary because at nop/idle (and CS active) only 0xff is
* on the data/command line)
*/
/** Data token start byte, Start Single Block Read */
pub const SD_START_DATA_SINGLE_BLOCK_READ: u8 = 0xFE;
/** Data token start byte, Start Multiple Block Read */
pub const SD_START_DATA_MULTIPLE_BLOCK_READ: u8 = 0xFE;
/** Data token start byte, Start Single Block Write */
pub const SD_START_DATA_SINGLE_BLOCK_WRITE: u8 = 0xFE;
/** Data token start byte, Start Multiple Block Write */
pub const SD_START_DATA_MULTIPLE_BLOCK_WRITE: u8 = 0xFC;
pub const SEC_LEN: usize = 512;
/** SD commands */
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[allow(unused)]
pub enum CMD {
/** Software reset */
CMD0 = 0,
/** Check voltage range (SDC V2) */
CMD8 = 8,
/** Read CSD register */
CMD9 = 9,
/** Read CID register */
CMD10 = 10,
/** Stop to read data */
CMD12 = 12,
/** Change R/W block size */
CMD16 = 16,
/** Read block */
CMD17 = 17,
/** Read multiple blocks */
CMD18 = 18,
/** Number of blocks to erase (SDC) */
ACMD23 = 23,
/** Write a block */
CMD24 = 24,
/** Write multiple blocks */
CMD25 = 25,
/** Initiate initialization process (SDC) */
ACMD41 = 41,
/** Leading command for ACMD* */
CMD55 = 55,
/** Read OCR */
CMD58 = 58,
/** Enable/disable CRC check */
CMD59 = 59,
}
#[allow(unused)]
#[derive(Debug, Copy, Clone)]
pub enum InitError {
CMDFailed(CMD, u8),
CardCapacityStatusNotSet([u8; 4]),
CannotGetCardInfo,
}
/**
* Card Specific Data: CSD Register
*/
#[derive(Debug, Copy, Clone)]
pub struct SDCardCSD {
pub CSDStruct: u8, /* CSD structure */
pub SysSpecVersion: u8, /* System specification version */
pub Reserved1: u8, /* Reserved */
pub TAAC: u8, /* Data read access-time 1 */
pub NSAC: u8, /* Data read access-time 2 in CLK cycles */
pub MaxBusClkFrec: u8, /* Max. bus clock frequency */
pub CardComdClasses: u16, /* Card command classes */
pub RdBlockLen: u8, /* Max. read data block length */
pub PartBlockRead: u8, /* Partial blocks for read allowed */
pub WrBlockMisalign: u8, /* Write block misalignment */
pub RdBlockMisalign: u8, /* Read block misalignment */
pub DSRImpl: u8, /* DSR implemented */
pub Reserved2: u8, /* Reserved */
pub DeviceSize: u32, /* Device Size */
//MaxRdCurrentVDDMin: u8, /* Max. read current @ VDD min */
//MaxRdCurrentVDDMax: u8, /* Max. read current @ VDD max */
//MaxWrCurrentVDDMin: u8, /* Max. write current @ VDD min */
//MaxWrCurrentVDDMax: u8, /* Max. write current @ VDD max */
//DeviceSizeMul: u8, /* Device size multiplier */
pub EraseGrSize: u8, /* Erase group size */
pub EraseGrMul: u8, /* Erase group size multiplier */
pub WrProtectGrSize: u8, /* Write protect group size */
pub WrProtectGrEnable: u8, /* Write protect group enable */
pub ManDeflECC: u8, /* Manufacturer default ECC */
pub WrSpeedFact: u8, /* Write speed factor */
pub MaxWrBlockLen: u8, /* Max. write data block length */
pub WriteBlockPaPartial: u8, /* Partial blocks for write allowed */
pub Reserved3: u8, /* Reserded */
pub ContentProtectAppli: u8, /* Content protection application */
pub FileFormatGroup: u8, /* File format group */
pub CopyFlag: u8, /* Copy flag (OTP) */
pub PermWrProtect: u8, /* Permanent write protection */
pub TempWrProtect: u8, /* Temporary write protection */
pub FileFormat: u8, /* File Format */
pub ECC: u8, /* ECC code */
pub CSD_CRC: u8, /* CSD CRC */
pub Reserved4: u8, /* always 1*/
}
/**
* Card Identification Data: CID Register
*/
#[derive(Debug, Copy, Clone)]
pub struct SDCardCID {
pub ManufacturerID: u8, /* ManufacturerID */
pub OEM_AppliID: u16, /* OEM/Application ID */
pub ProdName1: u32, /* Product Name part1 */
pub ProdName2: u8, /* Product Name part2*/
pub ProdRev: u8, /* Product Revision */
pub ProdSN: u32, /* Product Serial Number */
pub Reserved1: u8, /* Reserved1 */
pub ManufactDate: u16, /* Manufacturing Date */
pub CID_CRC: u8, /* CID CRC */
pub Reserved2: u8, /* always 1 */
}
/**
* Card information
*/
#[derive(Debug, Copy, Clone)]
pub struct SDCardInfo {
pub SD_csd: SDCardCSD,
pub SD_cid: SDCardCID,
pub CardCapacity: u64, /* Card Capacity */
pub CardBlockSize: u64, /* Card Block Size */
}
impl</*'a,*/ X: SPI> SDCard</*'a,*/ X> {
pub fn new(
spi: X,
spi_cs: u32,
cs_gpionum: u8, /*, dmac: &'a DMAC, channel: dma_channel*/
) -> Self {
Self {
spi,
spi_cs,
cs_gpionum,
/*
dmac,
channel,
*/
}
}
fn CS_HIGH(&self) {
gpiohs::set_pin(self.cs_gpionum, true);
}
fn CS_LOW(&self) {
gpiohs::set_pin(self.cs_gpionum, false);
}
fn HIGH_SPEED_ENABLE(&self) {
self.spi.set_clk_rate(10000000);
}
fn lowlevel_init(&self) {
gpiohs::set_direction(self.cs_gpionum, gpio::direction::OUTPUT);
self.spi.set_clk_rate(200000);
}
fn write_data(&self, data: &[u8]) {
self.spi.configure(
work_mode::MODE0,
frame_format::STANDARD,
8, /* data bits */
0, /* endian */
0, /*instruction length*/
0, /*address length*/
0, /*wait cycles*/
aitm::STANDARD,
tmod::TRANS,
);
self.spi.send_data(self.spi_cs, data);
}
/*
fn write_data_dma(&self, data: &[u32]) {
self.spi.configure(
work_mode::MODE0,
frame_format::STANDARD,
8, /* data bits */
0, /* endian */
0, /*instruction length*/
0, /*address length*/
0, /*wait cycles*/
aitm::STANDARD,
tmod::TRANS,
);
self.spi
.send_data_dma(self.dmac, self.channel, self.spi_cs, data);
}
*/
fn read_data(&self, data: &mut [u8]) {
self.spi.configure(
work_mode::MODE0,
frame_format::STANDARD,
8, /* data bits */
0, /* endian */
0, /*instruction length*/
0, /*address length*/
0, /*wait cycles*/
aitm::STANDARD,
tmod::RECV,
);
self.spi.recv_data(self.spi_cs, data);
}
/*
fn read_data_dma(&self, data: &mut [u32]) {
self.spi.configure(
work_mode::MODE0,
frame_format::STANDARD,
8, /* data bits */
0, /* endian */
0, /*instruction length*/
0, /*address length*/
0, /*wait cycles*/
aitm::STANDARD,
tmod::RECV,
);
self.spi
.recv_data_dma(self.dmac, self.channel, self.spi_cs, data);
}
*/
/*
* Send 5 bytes command to the SD card.
* @param cmd: The user expected command to send to SD card.
* @param arg: The command argument.
* @param crc: The CRC.
* @retval None
*/
fn send_cmd(&self, cmd: CMD, arg: u32, crc: u8) {
/* SD chip select low */
self.CS_LOW();
/* Send the Cmd bytes */
self.write_data(&[
/* Construct byte 1 */
((cmd as u8) | 0x40),
/* Construct byte 2 */
(arg >> 24) as u8,
/* Construct byte 3 */
((arg >> 16) & 0xff) as u8,
/* Construct byte 4 */
((arg >> 8) & 0xff) as u8,
/* Construct byte 5 */
(arg & 0xff) as u8,
/* Construct CRC: byte 6 */
crc,
]);
}
/* Send end-command sequence to SD card */
fn end_cmd(&self) {
/* SD chip select high */
self.CS_HIGH();
/* Send the cmd byte */
self.write_data(&[0xff]);
}
/*
* Returns the SD response.
* @param None
* @retval The SD Response:
* - 0xFF: Sequence failed
* - 0: Sequence succeed
*/
fn get_response(&self) -> u8 {
let result = &mut [0u8];
let mut timeout = 0x0FFF;
/* Check if response is got or a timeout is happen */
while timeout != 0 {
self.read_data(result);
/* Right response got */
if result[0] != 0xFF {
return result[0];
}
timeout -= 1;
}
/* After time out */
0xFF
}
/*
* Get SD card data response.
* @param None
* @retval The SD status: Read data response xxx0<status>1
* - status 010: Data accepted
* - status 101: Data rejected due to a crc error
* - status 110: Data rejected due to a Write error.
* - status 111: Data rejected due to other error.
*/
fn get_dataresponse(&self) -> u8 {
let response = &mut [0u8];
/* Read response */
self.read_data(response);
/* Mask unused bits */
response[0] &= 0x1F;
if response[0] != 0x05 {
return 0xFF;
}
/* Wait null data */
self.read_data(response);
while response[0] == 0 {
self.read_data(response);
}
/* Return response */
0
}
/*
* Read the CSD card register
* Reading the contents of the CSD register in SPI mode is a simple
* read-block transaction.
* @param SD_csd: pointer on an SCD register structure
* @retval The SD Response:
* - `Err()`: Sequence failed
* - `Ok(info)`: Sequence succeed
*/
fn get_csdregister(&self) -> Result<SDCardCSD, ()> {
let mut csd_tab = [0u8; 18];
/* Send CMD9 (CSD register) */
self.send_cmd(CMD::CMD9, 0, 0);
/* Wait for response in the R1 format (0x00 is no errors) */
if self.get_response() != 0x00 {
self.end_cmd();
return Err(());
}
if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
self.end_cmd();
return Err(());
}
/* Store CSD register value on csd_tab */
/* Get CRC bytes (not really needed by us, but required by SD) */
self.read_data(&mut csd_tab);
self.end_cmd();
/* see also: https://cdn-shop.adafruit.com/datasheets/TS16GUSDHC6.pdf */
Ok(SDCardCSD {
/* Byte 0 */
CSDStruct: (csd_tab[0] & 0xC0) >> 6,
SysSpecVersion: (csd_tab[0] & 0x3C) >> 2,
Reserved1: csd_tab[0] & 0x03,
/* Byte 1 */
TAAC: csd_tab[1],
/* Byte 2 */
NSAC: csd_tab[2],
/* Byte 3 */
MaxBusClkFrec: csd_tab[3],
/* Byte 4, 5 */
CardComdClasses: (u16::from(csd_tab[4]) << 4) | ((u16::from(csd_tab[5]) & 0xF0) >> 4),
/* Byte 5 */
RdBlockLen: csd_tab[5] & 0x0F,
/* Byte 6 */
PartBlockRead: (csd_tab[6] & 0x80) >> 7,
WrBlockMisalign: (csd_tab[6] & 0x40) >> 6,
RdBlockMisalign: (csd_tab[6] & 0x20) >> 5,
DSRImpl: (csd_tab[6] & 0x10) >> 4,
Reserved2: 0,
// DeviceSize: (csd_tab[6] & 0x03) << 10,
/* Byte 7, 8, 9 */
DeviceSize: ((u32::from(csd_tab[7]) & 0x3F) << 16)
| (u32::from(csd_tab[8]) << 8)
| u32::from(csd_tab[9]),
/* Byte 10 */
EraseGrSize: (csd_tab[10] & 0x40) >> 6,
/* Byte 10, 11 */
EraseGrMul: ((csd_tab[10] & 0x3F) << 1) | ((csd_tab[11] & 0x80) >> 7),
/* Byte 11 */
WrProtectGrSize: (csd_tab[11] & 0x7F),
/* Byte 12 */
WrProtectGrEnable: (csd_tab[12] & 0x80) >> 7,
ManDeflECC: (csd_tab[12] & 0x60) >> 5,
WrSpeedFact: (csd_tab[12] & 0x1C) >> 2,
/* Byte 12,13 */
MaxWrBlockLen: ((csd_tab[12] & 0x03) << 2) | ((csd_tab[13] & 0xC0) >> 6),
/* Byte 13 */
WriteBlockPaPartial: (csd_tab[13] & 0x20) >> 5,
Reserved3: 0,
ContentProtectAppli: (csd_tab[13] & 0x01),
/* Byte 14 */
FileFormatGroup: (csd_tab[14] & 0x80) >> 7,
CopyFlag: (csd_tab[14] & 0x40) >> 6,
PermWrProtect: (csd_tab[14] & 0x20) >> 5,
TempWrProtect: (csd_tab[14] & 0x10) >> 4,
FileFormat: (csd_tab[14] & 0x0C) >> 2,
ECC: (csd_tab[14] & 0x03),
/* Byte 15 */
CSD_CRC: (csd_tab[15] & 0xFE) >> 1,
Reserved4: 1,
/* Return the response */
})
}
/*
* Read the CID card register.
* Reading the contents of the CID register in SPI mode is a simple
* read-block transaction.
* @param SD_cid: pointer on an CID register structure
* @retval The SD Response:
* - `Err()`: Sequence failed
* - `Ok(info)`: Sequence succeed
*/
fn get_cidregister(&self) -> Result<SDCardCID, ()> {
let mut cid_tab = [0u8; 18];
/* Send CMD10 (CID register) */
self.send_cmd(CMD::CMD10, 0, 0);
/* Wait for response in the R1 format (0x00 is no errors) */
if self.get_response() != 0x00 {
self.end_cmd();
return Err(());
}
if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
self.end_cmd();
return Err(());
}
/* Store CID register value on cid_tab */
/* Get CRC bytes (not really needed by us, but required by SD) */
self.read_data(&mut cid_tab);
self.end_cmd();
Ok(SDCardCID {
/* Byte 0 */
ManufacturerID: cid_tab[0],
/* Byte 1, 2 */
OEM_AppliID: (u16::from(cid_tab[1]) << 8) | u16::from(cid_tab[2]),
/* Byte 3, 4, 5, 6 */
ProdName1: (u32::from(cid_tab[3]) << 24)
| (u32::from(cid_tab[4]) << 16)
| (u32::from(cid_tab[5]) << 8)
| u32::from(cid_tab[6]),
/* Byte 7 */
ProdName2: cid_tab[7],
/* Byte 8 */
ProdRev: cid_tab[8],
/* Byte 9, 10, 11, 12 */
ProdSN: (u32::from(cid_tab[9]) << 24)
| (u32::from(cid_tab[10]) << 16)
| (u32::from(cid_tab[11]) << 8)
| u32::from(cid_tab[12]),
/* Byte 13, 14 */
Reserved1: (cid_tab[13] & 0xF0) >> 4,
ManufactDate: ((u16::from(cid_tab[13]) & 0x0F) << 8) | u16::from(cid_tab[14]),
/* Byte 15 */
CID_CRC: (cid_tab[15] & 0xFE) >> 1,
Reserved2: 1,
})
}
/*
* Returns information about specific card.
* @param cardinfo: pointer to a SD_CardInfo structure that contains all SD
* card information.
* @retval The SD Response:
* - `Err(())`: Sequence failed
* - `Ok(info)`: Sequence succeed
*/
fn get_cardinfo(&self) -> Result<SDCardInfo, ()> {
let mut info = SDCardInfo {
SD_csd: self.get_csdregister()?,
SD_cid: self.get_cidregister()?,
CardCapacity: 0,
CardBlockSize: 0,
};
info.CardBlockSize = 1 << u64::from(info.SD_csd.RdBlockLen);
info.CardCapacity = (u64::from(info.SD_csd.DeviceSize) + 1) * 1024 * info.CardBlockSize;
Ok(info)
}
/*
* Initializes the SD/SD communication in SPI mode.
* @param None
* @retval The SD Response info if succeeeded, otherwise Err
*/
pub fn init(&self) -> Result<SDCardInfo, InitError> {
/* Initialize SD_SPI */
self.lowlevel_init();
/* SD chip select high */
self.CS_HIGH();
/* NOTE: this reset doesn't always seem to work if the SD access was broken off in the
* middle of an operation: CMDFailed(CMD0, 127). */
/* Send dummy byte 0xFF, 10 times with CS high */
/* Rise CS and MOSI for 80 clocks cycles */
/* Send dummy byte 0xFF */
self.write_data(&[0xff; 10]);
/*------------Put SD in SPI mode--------------*/
/* SD initialized and set to SPI mode properly */
/* Send software reset */
self.send_cmd(CMD::CMD0, 0, 0x95);
let result = self.get_response();
self.end_cmd();
if result != 0x01 {
return Err(InitError::CMDFailed(CMD::CMD0, result));
}
/* Check voltage range */
self.send_cmd(CMD::CMD8, 0x01AA, 0x87);
/* 0x01 or 0x05 */
let result = self.get_response();
let mut frame = [0u8; 4];
self.read_data(&mut frame);
self.end_cmd();
if result != 0x01 {
return Err(InitError::CMDFailed(CMD::CMD8, result));
}
let mut index = 255;
while index != 0 {
/* <ACMD> */
self.send_cmd(CMD::CMD55, 0, 0);
let result = self.get_response();
self.end_cmd();
if result != 0x01 {
return Err(InitError::CMDFailed(CMD::CMD55, result));
}
/* Initiate SDC initialization process */
self.send_cmd(CMD::ACMD41, 0x40000000, 0);
let result = self.get_response();
self.end_cmd();
if result == 0x00 {
break;
}
index -= 1;
}
if index == 0 {
return Err(InitError::CMDFailed(CMD::ACMD41, result));
}
index = 255;
let mut frame = [0u8; 4];
while index != 0 {
/* Read OCR */
self.send_cmd(CMD::CMD58, 0, 1);
let result = self.get_response();
self.read_data(&mut frame);
self.end_cmd();
if result == 0 {
break;
}
index -= 1;
}
if index == 0 {
return Err(InitError::CMDFailed(CMD::CMD58, result));
}
if (frame[0] & 0x40) == 0 {
return Err(InitError::CardCapacityStatusNotSet(frame));
}
self.HIGH_SPEED_ENABLE();
self.get_cardinfo()
.map_err(|_| InitError::CannotGetCardInfo)
}
/*
* Reads a block of data from the SD.
* @param data_buf: slice that receives the data read from the SD.
* @param sector: SD's internal address to read from.
* @retval The SD Response:
* - `Err(())`: Sequence failed
* - `Ok(())`: Sequence succeed
*/
pub fn read_sector(&self, data_buf: &mut [u8], sector: u32) -> Result<(), ()> {
assert!(data_buf.len() >= SEC_LEN && (data_buf.len() % SEC_LEN) == 0);
/* Send CMD17 to read one block, or CMD18 for multiple */
let flag = if data_buf.len() == SEC_LEN {
self.send_cmd(CMD::CMD17, sector, 0);
false
} else {
self.send_cmd(CMD::CMD18, sector, 0);
true
};
/* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */
if self.get_response() != 0x00 {
self.end_cmd();
return Err(());
}
let mut error = false;
//let mut dma_chunk = [0u32; SEC_LEN];
let mut tmp_chunk = [0u8; SEC_LEN];
for chunk in data_buf.chunks_mut(SEC_LEN) {
if self.get_response() != SD_START_DATA_SINGLE_BLOCK_READ {
error = true;
break;
}
/* Read the SD block data : read NumByteToRead data */
//self.read_data_dma(&mut dma_chunk);
self.read_data(&mut tmp_chunk);
/* Place the data received as u32 units from DMA into the u8 target buffer */
for (a, b) in chunk.iter_mut().zip(/*dma_chunk*/ tmp_chunk.iter()) {
//*a = (b & 0xff) as u8;
*a = *b;
}
/* Get CRC bytes (not really needed by us, but required by SD) */
let mut frame = [0u8; 2];
self.read_data(&mut frame);
}
self.end_cmd();
if flag {
self.send_cmd(CMD::CMD12, 0, 0);
self.get_response();
self.end_cmd();
self.end_cmd();
}
/* It is an error if not everything requested was read */
if error {
Err(())
} else {
Ok(())
}
}
/*
* Writes a block to the SD
* @param data_buf: slice containing the data to be written to the SD.
* @param sector: address to write on.
* @retval The SD Response:
* - `Err(())`: Sequence failed
* - `Ok(())`: Sequence succeed
*/
pub fn write_sector(&self, data_buf: &[u8], sector: u32) -> Result<(), ()> {
assert!(data_buf.len() >= SEC_LEN && (data_buf.len() % SEC_LEN) == 0);
let mut frame = [0xff, 0x00];
if data_buf.len() == SEC_LEN {
frame[1] = SD_START_DATA_SINGLE_BLOCK_WRITE;
self.send_cmd(CMD::CMD24, sector, 0);
} else {
frame[1] = SD_START_DATA_MULTIPLE_BLOCK_WRITE;
self.send_cmd(
CMD::ACMD23,
(data_buf.len() / SEC_LEN).try_into().unwrap(),
0,
);
self.get_response();
self.end_cmd();
self.send_cmd(CMD::CMD25, sector, 0);
}
/* Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */
if self.get_response() != 0x00 {
self.end_cmd();
return Err(());
}
//let mut dma_chunk = [0u32; SEC_LEN];
let mut tmp_chunk = [0u8; SEC_LEN];
for chunk in data_buf.chunks(SEC_LEN) {
/* Send the data token to signify the start of the data */
self.write_data(&frame);
/* Write the block data to SD : write count data by block */
for (a, &b) in /*dma_chunk*/ tmp_chunk.iter_mut().zip(chunk.iter()) {
//*a = b.into();
*a = b;
}
//self.write_data_dma(&mut dma_chunk);
self.write_data(&tmp_chunk);
/* Put dummy CRC bytes */
self.write_data(&[0xff, 0xff]);
/* Read data response */
if self.get_dataresponse() != 0x00 {
self.end_cmd();
return Err(());
}
}
self.end_cmd();
self.end_cmd();
Ok(())
}
}
/** GPIOHS GPIO number to use for controlling the SD card CS pin */
const SD_CS_GPIONUM: u8 = 7;
/** CS value passed to SPI controller, this is a dummy value as SPI0_CS3 is not mapping to anything
* in the FPIOA */
const SD_CS: u32 = 3;
/** Connect pins to internal functions */
fn io_init() {
fpioa::set_function(io::SPI0_SCLK, fpioa::function::SPI0_SCLK);
fpioa::set_function(io::SPI0_MOSI, fpioa::function::SPI0_D0);
fpioa::set_function(io::SPI0_MISO, fpioa::function::SPI0_D1);
fpioa::set_function(io::SPI0_CS0, fpioa::function::gpiohs(SD_CS_GPIONUM));
fpioa::set_io_pull(io::SPI0_CS0, fpioa::pull::DOWN); // GPIO output=pull down
}
lazy_static! {
static ref PERIPHERALS: UPIntrFreeCell<Peripherals> =
unsafe { UPIntrFreeCell::new(Peripherals::take().unwrap()) };
}
fn init_sdcard() -> SDCard<SPIImpl<SPI0>> {
// wait previous output
usleep(100000);
let peripherals = unsafe { Peripherals::steal() };
sysctl::pll_set_freq(sysctl::pll::PLL0, 800_000_000).unwrap();
sysctl::pll_set_freq(sysctl::pll::PLL1, 300_000_000).unwrap();
sysctl::pll_set_freq(sysctl::pll::PLL2, 45_158_400).unwrap();
let clocks = k210_hal::clock::Clocks::new();
peripherals.UARTHS.configure(115_200.bps(), &clocks);
io_init();
let spi = peripherals.SPI0.constrain();
let sd = SDCard::new(spi, SD_CS, SD_CS_GPIONUM);
let info = sd.init().unwrap();
let num_sectors = info.CardCapacity / 512;
assert!(num_sectors > 0);
println!("init sdcard!");
sd
}
pub struct SDCardWrapper(UPIntrFreeCell<SDCard<SPIImpl<SPI0>>>);
impl SDCardWrapper {
pub fn new() -> Self {
unsafe { Self(UPIntrFreeCell::new(init_sdcard())) }
}
}
impl BlockDevice for SDCardWrapper {
fn read_block(&self, block_id: usize, buf: &mut [u8]) {
self.0
.exclusive_access()
.read_sector(buf, block_id as u32)
.unwrap();
}
fn write_block(&self, block_id: usize, buf: &[u8]) {
self.0
.exclusive_access()
.write_sector(buf, block_id as u32)
.unwrap();
}
fn handle_irq(&self) {
unimplemented!();
}
}
mod ns16550a;
#[cfg(feature = "board_qemu")]
use crate::board::CharDeviceImpl;
use alloc::sync::Arc;
use lazy_static::*;
......@@ -11,7 +10,7 @@ pub trait CharDevice {
fn write(&self, ch: u8);
fn handle_irq(&self);
}
#[cfg(feature = "board_qemu")]
lazy_static! {
pub static ref UART: Arc<CharDeviceImpl> = Arc::new(CharDeviceImpl::new());
}
......@@ -9,7 +9,6 @@ use embedded_graphics::{
prelude::{Point, Size},
text::Text,
};
use k210_hal::cache::Uncache;
use virtio_drivers::{VirtIOHeader, VirtIOInput};
use crate::drivers::bus::virtio::VirtioHal;
use virtio_input_decoder::{Decoder, Key, KeyType};
......
pub mod block;
pub mod chardev;
#[cfg(feature = "board_qemu")]
pub mod gpu;
#[cfg(feature = "board_qemu")]
pub mod input;
#[cfg(feature = "board_qemu")]
pub mod bus;
pub mod plic;
pub use block::BLOCK_DEVICE;
#[cfg(feature = "board_qemu")]
pub use chardev::UART;
#[cfg(feature = "board_qemu")]
pub use gpu::*;
#[cfg(feature = "board_qemu")]
pub use input::*;
#[cfg(feature = "board_qemu")]
pub use bus::*;
use super::File;
use crate::drivers::chardev::CharDevice;
#[cfg(feature = "board_qemu")]
use crate::drivers::chardev::UART;
use crate::mm::UserBuffer;
#[cfg(feature = "board_k210")]
use crate::sbi::console_getchar;
#[cfg(feature = "board_k210")]
use crate::task::suspend_current_and_run_next;
pub struct Stdin;
pub struct Stdout;
......@@ -18,7 +13,6 @@ impl File for Stdin {
fn writable(&self) -> bool {
false
}
#[cfg(feature = "board_qemu")]
fn read(&self, mut user_buf: UserBuffer) -> usize {
assert_eq!(user_buf.len(), 1);
//println!("before UART.read() in Stdin::read()");
......@@ -28,27 +22,6 @@ impl File for Stdin {
}
1
}
#[cfg(feature = "board_k210")]
fn read(&self, mut user_buf: UserBuffer) -> usize {
assert_eq!(user_buf.len(), 1);
// busy loop
let mut c: usize;
loop {
c = console_getchar();
if c == 0 {
suspend_current_and_run_next();
continue;
} else {
break;
}
}
let ch = c as u8;
unsafe {
user_buf.buffers[0].as_mut_ptr().write_volatile(ch);
}
1
}
fn write(&self, _user_buf: UserBuffer) -> usize {
panic!("Cannot write to stdin!");
}
......
......@@ -4,6 +4,7 @@ mod icon;
mod image;
mod panel;
mod terminal;
use alloc::sync::Arc;
pub use button::*;
use core::any::Any;
......
OUTPUT_ARCH(riscv)
ENTRY(_start)
BASE_ADDRESS = 0x80020000;
SECTIONS
{
. = BASE_ADDRESS;
skernel = .;
stext = .;
.text : {
*(.text.entry)
. = ALIGN(4K);
strampoline = .;
*(.text.trampoline);
. = ALIGN(4K);
*(.text .text.*)
}
. = ALIGN(4K);
etext = .;
srodata = .;
.rodata : {
*(.rodata .rodata.*)
*(.srodata .srodata.*)
}
. = ALIGN(4K);
erodata = .;
sdata = .;
.data : {
*(.data .data.*)
*(.sdata .sdata.*)
}
. = ALIGN(4K);
edata = .;
sbss_with_stack = .;
.bss : {
*(.bss.stack)
sbss = .;
*(.bss .bss.*)
*(.sbss .sbss.*)
}
. = ALIGN(4K);
ebss = .;
ekernel = .;
/DISCARD/ : {
*(.eh_frame)
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
#![no_main]
#![feature(panic_info_message)]
#![feature(alloc_error_handler)]
#[cfg(feature = "board_qemu")]
use crate::drivers::{GPU_DEVICE, KEYBOARD_DEVICE, MOUSE_DEVICE};
extern crate alloc;
......@@ -10,10 +10,6 @@ extern crate alloc;
#[macro_use]
extern crate bitflags;
#[cfg(feature = "board_k210")]
#[path = "boards/k210.rs"]
mod board;
#[cfg(not(any(feature = "board_k210")))]
#[path = "boards/qemu.rs"]
mod board;
......@@ -22,7 +18,6 @@ mod console;
mod config;
mod drivers;
mod fs;
#[cfg(feature = "board_qemu")]
mod gui;
mod lang_items;
mod mm;
......@@ -61,13 +56,10 @@ pub fn rust_main() -> ! {
clear_bss();
mm::init();
println!("KERN: init gpu");
#[cfg(feature = "board_qemu")]
GPU_DEVICE.clone();
println!("KERN: init keyboard");
#[cfg(feature = "board_qemu")]
KEYBOARD_DEVICE.clone();
println!("KERN: init mouse");
#[cfg(feature = "board_qemu")]
MOUSE_DEVICE.clone();
println!("KERN: init trap");
trap::init();
......
......@@ -40,13 +40,7 @@ pub fn console_getchar() -> usize {
sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0)
}
#[cfg(feature = "board_qemu")]
use crate::board::QEMUExit;
pub fn shutdown(exit_code: usize) -> ! {
#[cfg(feature = "board_k210")]
sbi_call(SBI_SHUTDOWN, exit_code, 0, 0);
#[cfg(feature = "board_qemu")]
crate::board::QEMU_EXIT_HANDLE.exit_failure();
#[cfg(feature = "board_k210")]
panic!("It should shutdown!");
crate::board::QEMU_EXIT_HANDLE.exit_failure()
}
......@@ -27,22 +27,18 @@ const SYSCALL_CONDVAR_SIGNAL: usize = 1031;
const SYSCALL_CONDVAR_WAIT: usize = 1032;
const SYSCALL_CREATE_DESKTOP: usize = 2000;
mod fs;
#[cfg(feature = "board_qemu")]
mod gui;
mod process;
mod sync;
mod thread;
#[cfg(feature = "board_qemu")]
pub use self::gui::create_desktop;
use fs::*;
#[cfg(feature = "board_qemu")]
pub use gui::PAD;
use process::*;
use sync::*;
use thread::*;
#[cfg(feature = "board_qemu")]
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
match syscall_id {
SYSCALL_DUP => sys_dup(args[0]),
......@@ -77,36 +73,3 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
}
}
#[cfg(feature = "board_k210")]
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
match syscall_id {
SYSCALL_DUP => sys_dup(args[0]),
SYSCALL_OPEN => sys_open(args[0] as *const u8, args[1] as u32),
SYSCALL_CLOSE => sys_close(args[0]),
SYSCALL_PIPE => sys_pipe(args[0] as *mut usize),
SYSCALL_READ => sys_read(args[0], args[1] as *const u8, args[2]),
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
SYSCALL_EXIT => sys_exit(args[0] as i32),
SYSCALL_SLEEP => sys_sleep(args[0]),
SYSCALL_YIELD => sys_yield(),
SYSCALL_KILL => sys_kill(args[0], args[1] as u32),
SYSCALL_GET_TIME => sys_get_time(),
SYSCALL_GETPID => sys_getpid(),
SYSCALL_FORK => sys_fork(),
SYSCALL_EXEC => sys_exec(args[0] as *const u8, args[1] as *const usize),
SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
SYSCALL_THREAD_CREATE => sys_thread_create(args[0], args[1]),
SYSCALL_GETTID => sys_gettid(),
SYSCALL_WAITTID => sys_waittid(args[0]) as isize,
SYSCALL_MUTEX_CREATE => sys_mutex_create(args[0] == 1),
SYSCALL_MUTEX_LOCK => sys_mutex_lock(args[0]),
SYSCALL_MUTEX_UNLOCK => sys_mutex_unlock(args[0]),
SYSCALL_SEMAPHORE_CREATE => sys_semaphore_create(args[0]),
SYSCALL_SEMAPHORE_UP => sys_semaphore_up(args[0]),
SYSCALL_SEMAPHORE_DOWN => sys_semaphore_down(args[0]),
SYSCALL_CONDVAR_CREATE => sys_condvar_create(args[0]),
SYSCALL_CONDVAR_SIGNAL => sys_condvar_signal(args[0]),
SYSCALL_CONDVAR_WAIT => sys_condvar_wait(args[0], args[1]),
_ => panic!("Unsupported syscall_id: {}", syscall_id),
}
}
......@@ -56,7 +56,6 @@ pub fn block_current_and_run_next() {
let task_cx_ptr = block_current_task();
schedule(task_cx_ptr);
}
#[cfg(feature = "board_qemu")]
use crate::board::QEMUExit;
pub fn exit_current_and_run_next(exit_code: i32) {
......@@ -75,7 +74,6 @@ pub fn exit_current_and_run_next(exit_code: i32) {
// the process should terminate at once
if tid == 0 {
let pid = process.getpid();
#[cfg(feature = "board_qemu")]
if pid == IDLE_PID {
println!(
"[kernel] Idle process exit with exit_code {} ...",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册