Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Baremetal xv6 ported to milkv duo #4

Open
wants to merge 10 commits into
base: riscv
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ mkfs
kernel/kernel
user/usys.S
.gdbinit
port/fip/fip.bin
port/image/output/*
24 changes: 21 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ OBJS = \
$K/sysfile.o \
$K/kernelvec.o \
$K/plic.o \
$K/virtio_disk.o
$K/ramdisk.o \
$K/i2c_designware.o \
$K/i2c_dev.o \
$K/uart_dev.o \
$K/adc_dev.o \
$K/pwm_dev.o \
$K/gpio_dev.o \
$K/spi_dev.o \

# riscv64-unknown-elf- or riscv64-linux-gnu-
# perhaps in /opt/riscv/bin
Expand Down Expand Up @@ -77,6 +84,7 @@ $K/kernel: $(OBJS) $K/kernel.ld $U/initcode
$(LD) $(LDFLAGS) -T $K/kernel.ld -o $K/kernel $(OBJS)
$(OBJDUMP) -S $K/kernel > $K/kernel.asm
$(OBJDUMP) -t $K/kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $K/kernel.sym
$(OBJCOPY) -S -O binary $K/kernel $K/kernel.bin

$U/initcode: $U/initcode.S
$(CC) $(CFLAGS) -march=rv64g -nostdinc -I. -Ikernel -c $U/initcode.S -o $U/initcode.o
Expand Down Expand Up @@ -132,19 +140,29 @@ UPROGS=\
$U/_grind\
$U/_wc\
$U/_zombie\
$U/_sleep\
$U/_uptime\
$U/_i2ctest\
$U/_uarttest\
$U/_adctest\
$U/_pwmtest\
$U/_gpiotest\
$U/_spitest\

fs.img: mkfs/mkfs README $(UPROGS)
mkfs/mkfs fs.img README $(UPROGS)
xxd -i fs.img > kernel/ramdisk.h

-include kernel/*.d user/*.d

clean:
rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \
*/*.o */*.d */*.asm */*.sym \
$U/initcode $U/initcode.out $K/kernel fs.img \
mkfs/mkfs .gdbinit \
mkfs/mkfs \
$U/usys.S \
$(UPROGS)
$(UPROGS) \
kernel/kernel.bin kernel/ramdisk.h

# try to generate a unique GDB port
GDBPORT = $(shell expr `id -u` % 5000 + 25000)
Expand Down
10 changes: 10 additions & 0 deletions kernel/adc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#define saradc_ctrl 0x004 // control register
#define saradc_status 0x008 // staus register
#define saradc_cyc_set 0x00c // saradc waveform setting register
#define saradc_ch1_result 0x014 // channel 1 result register
#define saradc_ch2_result 0x018 // channel 2 result register
#define saradc_ch3_result 0x01c // channel 3 result register
#define saradc_intr_en 0x020 // interrupt enable register
#define saradc_intr_clr 0x024 // interrupt clear register
#define saradc_intr_sta 0x028 // interrupt status register
#define saradc_intr_raw 0x02c // interrupt raw status registe
124 changes: 124 additions & 0 deletions kernel/adc_dev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include "types.h"
#include "memlayout.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "fs.h"
#include "file.h"
#include "riscv.h"
#include "defs.h"
#include "adc.h"

#define Reg(reg) ((volatile unsigned int *)(ADC0 + reg))
#define ReadReg(reg) (*(Reg(reg)))
#define WriteReg(reg, v) (*(Reg(reg)) = (v))

static int debug = 0;

int channel = -1;
struct spinlock adc_lock;

int
adcdev_read(int user_dst, uint64 dst, int n)
{
acquire(&adc_lock);

uchar tmp[2];
unsigned int chan_result = 0;

// allow adc to send interrupt
WriteReg(saradc_intr_en, 1);

// begin measure

WriteReg(saradc_ctrl, 1 | ReadReg(saradc_ctrl));

if (debug) {
printf("saradc_ctrl = %x %p\n", ReadReg(saradc_ctrl),
ReadReg(saradc_ctrl));
printf("sleep in adcdev_read\n");
}

sleep(&channel, &adc_lock);

// measure complete
if (channel == 1)
chan_result = ReadReg(saradc_ch1_result);
else if (channel == 2)
chan_result = ReadReg(saradc_ch2_result);
else if (channel == 3)
chan_result = ReadReg(saradc_ch3_result);

chan_result = chan_result & 0xFFF;

if (debug) printf("chan_result: %x %p\n", chan_result, chan_result);

tmp[0] = chan_result;
tmp[1] = chan_result >> 8;

release(&adc_lock);

if (either_copyout(user_dst, dst, tmp, n) == -1)
return -1;

return n;
}

int
adcdev_ioctl(int user_src, unsigned int cmd, unsigned long arg)
{
// cmd is not used
// arg is channel number

if (debug) {
printf("saradc_ctrl = %x %p\n", ReadReg(saradc_ctrl),
ReadReg(saradc_ctrl));
printf("saradc_cyc_set = %x %p\n", ReadReg(saradc_cyc_set),
ReadReg(saradc_cyc_set));
printf("arg: %d\n", arg);
}

WriteReg(saradc_ctrl, 1 << (4 + arg));

channel = arg;

return 0;
}

int
adcdev_close(void)
{
channel = -1;
return 0;
}

void
adcdev_init(void)
{
devsw[ADC].read = adcdev_read;
devsw[ADC].ioctl = adcdev_ioctl;
devsw[ADC].close = adcdev_close;

initlock(&adc_lock, "adc");
}

void
adcdev_intr(void)
{
if (debug) {
printf("adcdev_intr\n");
printf("saradc_intr_sta: %x %p\n", ReadReg(saradc_intr_sta),
ReadReg(saradc_intr_sta));
}
// clear interrupt
WriteReg(saradc_intr_clr, 1);

if (debug) {
printf("saradc_intr_sta: %x %p\n", ReadReg(saradc_intr_sta),
ReadReg(saradc_intr_sta));
}

// does not allow adc to send interrupt
WriteReg(saradc_intr_en, 0);

wakeup(&channel);
}
6 changes: 4 additions & 2 deletions kernel/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ bread(uint dev, uint blockno)

b = bget(dev, blockno);
if(!b->valid) {
virtio_disk_rw(b, 0);
// virtio_disk_rw(b, 0);
ramdiskrw(b, 0);
b->valid = 1;
}
return b;
Expand All @@ -108,7 +109,8 @@ bwrite(struct buf *b)
{
if(!holdingsleep(&b->lock))
panic("bwrite");
virtio_disk_rw(b, 1);
// virtio_disk_rw(b, 1);
ramdiskrw(b, 1);
}

// Release a locked buffer.
Expand Down
38 changes: 33 additions & 5 deletions kernel/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,30 @@ void consoleinit(void);
void consoleintr(int);
void consputc(int);

// i2c_dev.c
void i2cdev_init(void);

// i2c_designware.c
struct i2c_adapter* i2c_dw_init(short minor);
void i2c_dw_intr(void);
void i2c_dw_close(void);

// uart_dev.c
void uartdev_init(void);

// adc_dev.c
void adcdev_init(void);
void adcdev_intr(void);

// pwm_dev.c
void pwmdev_init(void);

// gpio_dev.c
void gpiodev_init(void);

// spi_dev.c
void spidev_init(void);

// exec.c
int exec(char*, char**);

Expand All @@ -33,6 +57,7 @@ void fileinit(void);
int fileread(struct file*, uint64, int n);
int filestat(struct file*, uint64 addr);
int filewrite(struct file*, uint64, int n);
int fileioctl(struct file *f, unsigned int cmd, unsigned long arg);

// fs.c
void fsinit(int);
Expand All @@ -56,8 +81,8 @@ void itrunc(struct inode*);

// ramdisk.c
void ramdiskinit(void);
void ramdiskintr(void);
void ramdiskrw(struct buf*);
// void ramdiskintr(void);
void ramdiskrw(struct buf*, int write);

// kalloc.c
void* kalloc(void);
Expand Down Expand Up @@ -135,6 +160,9 @@ char* strncpy(char*, const char*, int);

// syscall.c
void argint(int, int*);
void arguint(int, uint*);
void argulong(int, uint64*);
void argint(int, int*);
int argstr(int, char*, int);
void argaddr(int, uint64 *);
int fetchstr(uint64, char*, int);
Expand Down Expand Up @@ -181,9 +209,9 @@ int plic_claim(void);
void plic_complete(int);

// virtio_disk.c
void virtio_disk_init(void);
void virtio_disk_rw(struct buf *, int);
void virtio_disk_intr(void);
// void virtio_disk_init(void);
// void virtio_disk_rw(struct buf *, int);
// void virtio_disk_intr(void);

// number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
13 changes: 13 additions & 0 deletions kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ _entry:
addi a1, a1, 1
mul a0, a0, a1
add sp, sp, a0

li t3, 0
csrr t4, mhartid
bne t3, t4, callstart

la t0, bss_start
la t1, bss_end
li t2, 0
clearbss:
sb t2, 0(t0)
addi t0, t0, 1
bleu t0, t1, clearbss
callstart:
# jump to start() in start.c
call start
spin:
Expand Down
14 changes: 14 additions & 0 deletions kernel/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,17 @@ filewrite(struct file *f, uint64 addr, int n)
return ret;
}

int
fileioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
int ret = 0;

if(f->type == FD_DEVICE){
if(f->major < 0 || f->major >= NDEV || !devsw[f->major].ioctl)
return -1;
ret = devsw[f->major].ioctl(1, cmd, arg);
}

return ret;
}

9 changes: 9 additions & 0 deletions kernel/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,17 @@ struct inode {
struct devsw {
int (*read)(int, uint64, int);
int (*write)(int, uint64, int);
int (*ioctl)(int, unsigned int, unsigned long);
int (*open)(struct inode *);
int (*close)(void);
};

extern struct devsw devsw[];

#define CONSOLE 1
#define I2C 2
#define UART 3
#define ADC 4
#define PWM 5
#define GPIO 6
#define SPI 7
15 changes: 15 additions & 0 deletions kernel/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#define GPIO_SWPORTA_DR 0x000 // Port A data register
#define GPIO_SWPORTA_DDR 0x004 // Port A data direction register
#define GPIO_INTEN 0x030 // Interrupt enable register
#define GPIO_INTMASK 0x034 // Interrupt mask register
#define GPIO_INTTYPE_LEVEL 0x038 // Interrupt level register
#define GPIO_INT_POLARITY 0x03c // Interrupt polarity register
#define GPIO_INTSTATUS 0x040 // Interrupt status of Port A
#define GPIO_RAW_INTSTATUS 0x044 // Raw interrupt status of Port A (pre-masking)
#define GPIO_DEBOUNCE 0x048 // Debounce enable register
#define GPIO_PORTA_EOI 0x04c // Port A clear interrupt register
#define GPIO_EXT_PORTA 0x050 // Port A external port register
#define GPIO_LS_SYNC 0x060 // Level-sensitive sync enable register

#define SET_CHAN 0x1010
#define SET_DIR 0x2020
Loading