[add] laos using xv6-riscv thought
This commit is contained in:
@@ -1 +1,5 @@
|
|||||||
#include <device.hh>
|
#include <device.hh>
|
||||||
|
|
||||||
|
Device::Device(bool cacheable): cacheable_(cacheable) {}
|
||||||
|
|
||||||
|
bool Device::is_cacheable() { return cacheable_; }
|
||||||
@@ -3,9 +3,15 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
class Device {
|
class Device {
|
||||||
|
protected:
|
||||||
|
bool cacheable_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Device() = default;
|
Device(bool cacheable);
|
||||||
|
|
||||||
|
bool is_cacheable();
|
||||||
|
|
||||||
virtual const size_t &size() const = 0;
|
virtual const size_t &size() const = 0;
|
||||||
|
|
||||||
@@ -29,7 +35,9 @@ public:
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class WRDevice : public Device{
|
class WRDevice : public Device{
|
||||||
|
protected:
|
||||||
size_t devsiz;
|
size_t devsiz;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WRDevice(size_t siz);
|
WRDevice(size_t siz);
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <device.hh>
|
#include <device.hh>
|
||||||
|
|
||||||
class SystemBus {
|
class SystemBus {
|
||||||
std::map<uint64_t, Device *> iomap;
|
std::map<uint64_t, Device *> iomap_;
|
||||||
|
|
||||||
std::pair<const uint64_t, Device *> &finddev(uint64_t addr);
|
std::pair<const uint64_t, Device *> &finddev(uint64_t addr);
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
std::pair<const uint64_t, Device *> &SystemBus::finddev(uint64_t addr) {
|
std::pair<const uint64_t, Device *> &SystemBus::finddev(uint64_t addr) {
|
||||||
Device *dev = nullptr;
|
Device *dev = nullptr;
|
||||||
auto &&iter = iomap.upper_bound(addr);
|
auto &&iter = iomap_.upper_bound(addr);
|
||||||
if (iter == iomap.begin())
|
if (iter == iomap_.begin())
|
||||||
panic("device not found");
|
panic("device not found");
|
||||||
iter--;
|
iter--;
|
||||||
if (iter->first <= addr && iter->first + iter->second->size() > addr)
|
if (iter->first <= addr && iter->first + iter->second->size() > addr)
|
||||||
@@ -13,7 +13,7 @@ std::pair<const uint64_t, Device *> &SystemBus::finddev(uint64_t addr) {
|
|||||||
return *iter;
|
return *iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemBus::regdev(Device *dev, uint64_t addr) { iomap.emplace(addr, dev); }
|
void SystemBus::regdev(Device *dev, uint64_t addr) { iomap_.emplace(addr, dev); }
|
||||||
|
|
||||||
void SystemBus::write(char *buf, size_t addr, size_t len) {
|
void SystemBus::write(char *buf, size_t addr, size_t len) {
|
||||||
auto &&dev = finddev(addr);
|
auto &&dev = finddev(addr);
|
||||||
|
|||||||
@@ -7,23 +7,54 @@ OD := $(LA_BIN_PATH)/$(LA_PREFIX)objdump
|
|||||||
OC := $(LA_BIN_PATH)/$(LA_PREFIX)objcopy
|
OC := $(LA_BIN_PATH)/$(LA_PREFIX)objcopy
|
||||||
RE := $(LA_BIN_PATH)/$(LA_PREFIX)readelf
|
RE := $(LA_BIN_PATH)/$(LA_PREFIX)readelf
|
||||||
|
|
||||||
|
NPROC := $(shell nproc)
|
||||||
|
|
||||||
CMAKE := cmake
|
CMAKE := cmake
|
||||||
|
|
||||||
BUILD_DIR := build
|
BUILD_DIR := build
|
||||||
|
ABS_BUILD := $(CURDIR)/$(BUILD_DIR)
|
||||||
$(shell mkdir -p $(BUILD_DIR))
|
$(shell mkdir -p $(BUILD_DIR))
|
||||||
|
|
||||||
BIN := neula-os
|
BIN := neula-os
|
||||||
COMMON_DIR := COMMON
|
BINARY := $(BUILD_DIR)/$(BIN)
|
||||||
|
|
||||||
FILES := $(shell find src -name *.c)
|
TOP_SRC_DIR := src
|
||||||
|
SOURCE_DIRS := $(shell ls $(TOP_SRC_DIR)/* -d)
|
||||||
|
MK_DIRS := $(addprefix MAKE/,$(SOURCE_DIRS))
|
||||||
|
ALL_SRCS := $(shell find . -name '*.c')
|
||||||
|
LD_CSRIPT := kernel.ld
|
||||||
|
|
||||||
.PHONY: build clean
|
EXTRA_MACRO := # NDEBUG
|
||||||
|
|
||||||
build:
|
EXTRA_FLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -gdwarf-2
|
||||||
$(CC) $(FILES) -static --no-pic -march=loongarch32r -o $(BUILD_DIR)/$(BIN)
|
EXTRA_FLAGS += -MD
|
||||||
$(OD) -D $(BUILD_DIR)/$(BIN) > $(BUILD_DIR)/$(BIN).dump
|
EXTRA_FLAGS += -ffreestanding -fno-common -nostdlib
|
||||||
$(RE) -a $(BUILD_DIR)/$(BIN) > $(BUILD_DIR)/$(BIN).info
|
EXTRA_FLAGS += -I.
|
||||||
$(OC) $(BUILD_DIR)/$(BIN) -O binary $(BUILD_DIR)/$(BIN).bin
|
EXTRA_FLAGS += -fno-pie -no-pie
|
||||||
|
EXTRA_FLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
|
||||||
|
|
||||||
|
COMMONFLAGS := $(EXTRA_FLAGS) -march=loongarch32r
|
||||||
|
CPPFLAGS += $(addprefix -D,$(EXTRA_MACRO)) -I$(CURDIR)/include
|
||||||
|
CFLAGS += $(COMMONFLAGS) -O
|
||||||
|
LDFLAGS += $(COMMONFLAGS) -z max-page-size=4096 -T$(LD_CSRIPT)
|
||||||
|
|
||||||
|
.PHONY: all build clean
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
$(MK_DIRS): MAKE/%:% $(shell find $(%) -name '*.c')
|
||||||
|
@TOP_BUILD_DIR=$(ABS_BUILD) \
|
||||||
|
CC=$(CC) \
|
||||||
|
CPPFLAGS="$(CPPFLAGS)" \
|
||||||
|
CFLAGS="$(CFLAGS)" \
|
||||||
|
LDFLAGS="$(LDFLAGS)" \
|
||||||
|
$(MAKE) -C $< -j$(NPROC)
|
||||||
|
|
||||||
|
build: $(MK_DIRS)
|
||||||
|
@$(CC) -o $(BINARY) $(shell find $(BUILD_DIR) -name '*.o') $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||||
|
@$(OD) -D $(BINARY) > $(BINARY).dump
|
||||||
|
@$(RE) -a $(BINARY) > $(BINARY).info
|
||||||
|
@$(OC) $(BINARY) -O binary $(BINARY).bin
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR)
|
rm -rf $(BUILD_DIR)
|
||||||
8
laos/include/asm.h
Normal file
8
laos/include/asm.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
#ifndef ASM_H__
|
||||||
|
#define ASM_H__
|
||||||
|
|
||||||
|
#define CPUID 0x020
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
|
#include "defs.h"
|
||||||
|
|
||||||
#ifndef COMMON_H__
|
#ifndef COMMON_H__
|
||||||
#define COMMON_H__
|
#define COMMON_H__
|
||||||
|
|
||||||
|
void main();
|
||||||
|
void start();
|
||||||
|
void _entry() __attribute__ ((section (".entry")));
|
||||||
|
|
||||||
#endif // COMMON_H__
|
#endif // COMMON_H__
|
||||||
6
laos/include/defs.h
Normal file
6
laos/include/defs.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef DEFS_H__
|
||||||
|
#define DEFS_H__
|
||||||
|
|
||||||
|
#define NCPU 1
|
||||||
|
|
||||||
|
#endif
|
||||||
0
laos/include/util.h
Normal file
0
laos/include/util.h
Normal file
41
laos/kernel.ld
Normal file
41
laos/kernel.ld
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
OUTPUT_ARCH( "loongarch32r" )
|
||||||
|
ENTRY( _entry )
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ensure that entry.S / _entry is at 0x1C000000,
|
||||||
|
*/
|
||||||
|
. = 0x1C000000;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.entry)
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
*(.text .text.*)
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
PROVIDE(etext = .);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.srodata .srodata.*) /* do not need to distinguish this from .rodata */
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.sdata .sdata.*) /* do not need to distinguish this from .data */
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.data .data.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.sbss .sbss.*) /* do not need to distinguish this from .bss */
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.bss .bss.*)
|
||||||
|
}
|
||||||
|
|
||||||
|
PROVIDE(end = .);
|
||||||
|
}
|
||||||
28
laos/src/kernel/Makefile
Normal file
28
laos/src/kernel/Makefile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
CURNAME := kernel
|
||||||
|
BUILD_DIR := $(TOP_BUILD_DIR)/$(CURNAME)
|
||||||
|
|
||||||
|
CSRC := $(wildcard *.c)
|
||||||
|
OBJS := $(patsubst %.c,%.o,$(CSRC))
|
||||||
|
BUILD_OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS))
|
||||||
|
|
||||||
|
ASSRC := $(wildcard *.S)
|
||||||
|
ASOBJ := $(patsubst %.S,%.o,$(ASSRC))
|
||||||
|
BUILD_ASOBJ := $(addprefix $(BUILD_DIR)/,$(ASOBJ))
|
||||||
|
|
||||||
|
.PHONY: build all message
|
||||||
|
|
||||||
|
all: message build
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
@mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
$(BUILD_OBJS): $(BUILD_DIR)/%.o:%.c $(BUILD_DIR)
|
||||||
|
@$(CC) -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
|
||||||
|
|
||||||
|
$(BUILD_ASOBJ): $(BUILD_DIR)/%.o:%.S $(BUILD_DIR)
|
||||||
|
@$(CC) -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
|
||||||
|
|
||||||
|
build: $(BUILD_OBJS) $(BUILD_ASOBJ)
|
||||||
|
|
||||||
|
message:
|
||||||
|
@echo "building $(CURNAME)"
|
||||||
20
laos/src/kernel/entry.S
Normal file
20
laos/src/kernel/entry.S
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include "asm.h"
|
||||||
|
|
||||||
|
.section .entry
|
||||||
|
.global _entry
|
||||||
|
_entry:
|
||||||
|
# set up a stack for C.
|
||||||
|
# stack0 is declared in start.c,
|
||||||
|
# with a 4096-byte stack per CPU.
|
||||||
|
# sp = stack0 + (hartid * 4096)
|
||||||
|
la.global $sp, stack0
|
||||||
|
lu12i.w $a0, (1024*4 >> 12) & 0xfffff
|
||||||
|
addi.w $a0, $a0, 1024*4 & 0xfff
|
||||||
|
csrrd $a1, CPUID
|
||||||
|
addi.w $a1, $a1, 1
|
||||||
|
mul.w $a0, $a0, $a1
|
||||||
|
add.w $sp, $sp, $a0
|
||||||
|
# jump to start() in start.c
|
||||||
|
bl start
|
||||||
|
spin:
|
||||||
|
b spin
|
||||||
1
laos/src/kernel/kalloc.c
Normal file
1
laos/src/kernel/kalloc.c
Normal file
@@ -0,0 +1 @@
|
|||||||
|
extern char end[];
|
||||||
3
laos/src/kernel/main.c
Normal file
3
laos/src/kernel/main.c
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
void main() {
|
||||||
|
|
||||||
|
}
|
||||||
7
laos/src/kernel/start.c
Normal file
7
laos/src/kernel/start.c
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
__attribute__ ((aligned (16))) char stack0[4096 * NCPU];
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
|
||||||
|
}
|
||||||
1
laos/src/kernel/vm.c
Normal file
1
laos/src/kernel/vm.c
Normal file
@@ -0,0 +1 @@
|
|||||||
|
extern char etext[];
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
printf("%d", 123);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
21
laos/src/util/Makefile
Normal file
21
laos/src/util/Makefile
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
CURNAME := util
|
||||||
|
BUILD_DIR := $(TOP_BUILD_DIR)/$(CURNAME)
|
||||||
|
|
||||||
|
CSRC := $(wildcard *.c)
|
||||||
|
OBJS := $(patsubst %.c,%.o,$(CSRC))
|
||||||
|
BUILD_OBJS := $(addprefix $(BUILD_DIR)/,$(OBJS))
|
||||||
|
|
||||||
|
.PHONY: build all message
|
||||||
|
|
||||||
|
all: message build
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
@mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
$(BUILD_OBJS): $(BUILD_DIR)/%.o:%.c $(BUILD_DIR)
|
||||||
|
@$(CC) -c -o $@ $< $(CPPFLAGS) $(CFLAGS)
|
||||||
|
|
||||||
|
build: $(BUILD_OBJS)
|
||||||
|
|
||||||
|
message:
|
||||||
|
@echo "building $(CURNAME)"
|
||||||
1
laos/src/util/memops.c
Normal file
1
laos/src/util/memops.c
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include <assert.h>
|
||||||
261
lasim/la32r.cc
261
lasim/la32r.cc
@@ -134,6 +134,266 @@ struct CSRBaseInfo {
|
|||||||
// ----- ----- class defines ----- -----
|
// ----- ----- class defines ----- -----
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @bug no cached flag set
|
||||||
|
*/
|
||||||
|
class Cache {
|
||||||
|
private:
|
||||||
|
// mem addr
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// | tag | idx 5bit | byte sel 5 bit |
|
||||||
|
// -------------------------------------------------------
|
||||||
|
|
||||||
|
// info
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// | | MAT | PLV | cached | dirty |
|
||||||
|
// -------------------------------------------------------
|
||||||
|
using lane = u32[8];
|
||||||
|
lane mem_ck1[32];
|
||||||
|
u32 tags_ck1[32];
|
||||||
|
u32 info_ck1[32];
|
||||||
|
|
||||||
|
lane mem_ck2[32];
|
||||||
|
u32 tags_ck2[32];
|
||||||
|
u32 info_ck2[32];
|
||||||
|
|
||||||
|
// common info
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// | | recent |
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// recent => 1: recent use blk1, 0: recent use blk2
|
||||||
|
u32 info[32];
|
||||||
|
|
||||||
|
u32 load(u32 addr) {
|
||||||
|
auto word_sel = (addr >> 2) & 0b111;
|
||||||
|
auto idx = (addr >> 5) & 0b11111;
|
||||||
|
auto tag = addr >> 10;
|
||||||
|
|
||||||
|
if (tags_ck1[idx] == tag) {
|
||||||
|
// 将 recent 为设置为 1
|
||||||
|
info[idx] |= 0b1;
|
||||||
|
return mem_ck1[idx][word_sel];
|
||||||
|
} else if (tags_ck2[idx] == tag) {
|
||||||
|
// 将 recent 为设置为 0
|
||||||
|
info[idx] &= ~0b1;
|
||||||
|
return mem_ck2[idx][word_sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 laneaddr = addr << 10 | idx << 5;
|
||||||
|
u32 trans = 0;
|
||||||
|
|
||||||
|
if (info[idx] & 0b1) {
|
||||||
|
// 最近使用块 1
|
||||||
|
// 将块 2 替换下去
|
||||||
|
|
||||||
|
if (info_ck2[idx] & 0b1) {
|
||||||
|
u32 oldlaneaddr = tags_ck2[idx] << 10 | idx << 5;
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
trans = mem_ck2[idx][i];
|
||||||
|
sysbus->write32(trans, oldlaneaddr);
|
||||||
|
oldlaneaddr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags_ck2[idx] = tag;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
sysbus->read32(trans, laneaddr);
|
||||||
|
mem_ck2[idx][i] = trans;
|
||||||
|
laneaddr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 recent 为设置为 0
|
||||||
|
info[idx] &= ~0b1;
|
||||||
|
// 设置脏位
|
||||||
|
info_ck1[idx] &= ~0b1;
|
||||||
|
|
||||||
|
return mem_ck2[idx][word_sel];
|
||||||
|
} else {
|
||||||
|
// 最近使用块 2
|
||||||
|
// 将块 1 替换下去
|
||||||
|
|
||||||
|
if (info_ck1[idx] & 0b1) {
|
||||||
|
u32 oldlaneaddr = tags_ck1[idx] << 10 | idx << 5;
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
trans = mem_ck1[idx][i];
|
||||||
|
sysbus->write32(trans, oldlaneaddr);
|
||||||
|
oldlaneaddr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags_ck1[idx] = tag;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
sysbus->read32(trans, laneaddr);
|
||||||
|
mem_ck1[idx][i] = trans;
|
||||||
|
laneaddr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 recent 为设置为 1
|
||||||
|
info[idx] |= 0b1;
|
||||||
|
// 设置脏位
|
||||||
|
info_ck1[idx] &= ~0b1;
|
||||||
|
|
||||||
|
return mem_ck1[idx][word_sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void store(u32 addr, u32 data, u32 bytemsk) {
|
||||||
|
auto word_sel = (addr >> 2) & 0b111;
|
||||||
|
auto idx = (addr >> 5) & 0b11111;
|
||||||
|
auto tag = addr >> 10;
|
||||||
|
|
||||||
|
data = bytemsk & data;
|
||||||
|
|
||||||
|
if (tags_ck1[idx] == tag) {
|
||||||
|
// 将 recent 为设置为 1
|
||||||
|
info[idx] |= 0b1;
|
||||||
|
// 设置脏位
|
||||||
|
info_ck1[idx] |= 0b1;
|
||||||
|
|
||||||
|
mem_ck1[idx][word_sel] = data | (mem_ck1[idx][word_sel] & ~bytemsk);
|
||||||
|
return;
|
||||||
|
} else if (tags_ck2[idx] == tag) {
|
||||||
|
// 将 recent 为设置为 0
|
||||||
|
info[idx] &= ~0b1;
|
||||||
|
// 设置脏位
|
||||||
|
info_ck2[idx] |= 0b1;
|
||||||
|
|
||||||
|
mem_ck2[idx][word_sel] = data | (mem_ck2[idx][word_sel] & ~bytemsk);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 laneaddr = addr << 10 | idx << 5;
|
||||||
|
u32 trans = 0;
|
||||||
|
|
||||||
|
if (info[idx] & 0b1) {
|
||||||
|
// 最近使用块 1
|
||||||
|
// 将块 2 替换下去
|
||||||
|
|
||||||
|
if (info_ck2[idx] & 0b1) {
|
||||||
|
u32 oldlaneaddr = tags_ck2[idx] << 10 | idx << 5;
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
trans = mem_ck2[idx][i];
|
||||||
|
sysbus->write32(trans, oldlaneaddr);
|
||||||
|
oldlaneaddr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags_ck2[idx] = tag;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
sysbus->read32(trans, laneaddr);
|
||||||
|
mem_ck2[idx][i] = trans;
|
||||||
|
laneaddr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 recent 为设置为 0
|
||||||
|
info[idx] &= ~0b1;
|
||||||
|
// 设置脏位
|
||||||
|
info_ck2[idx] |= 0b1;
|
||||||
|
|
||||||
|
mem_ck2[idx][word_sel] = data | (mem_ck2[idx][word_sel] & ~bytemsk);
|
||||||
|
} else {
|
||||||
|
// 最近使用块 2
|
||||||
|
// 将块 1 替换下去
|
||||||
|
|
||||||
|
if (info_ck1[idx] & 0b1) {
|
||||||
|
u32 oldlaneaddr = tags_ck1[idx] << 10 | idx << 5;
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
trans = mem_ck1[idx][i];
|
||||||
|
sysbus->write32(trans, oldlaneaddr);
|
||||||
|
oldlaneaddr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags_ck1[idx] = tag;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
sysbus->read32(trans, laneaddr);
|
||||||
|
mem_ck1[idx][i] = trans;
|
||||||
|
laneaddr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 recent 为设置为 1
|
||||||
|
info[idx] |= 0b1;
|
||||||
|
// 设置脏位
|
||||||
|
info_ck1[idx] |= 0b1;
|
||||||
|
|
||||||
|
mem_ck1[idx][word_sel] = data | (mem_ck1[idx][word_sel] & ~bytemsk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prefetch(u32 addr, u32 hint) {
|
||||||
|
auto word_sel = (addr >> 2) & 0b111;
|
||||||
|
auto idx = (addr >> 5) & 0b11111;
|
||||||
|
auto tag = addr >> 10;
|
||||||
|
|
||||||
|
if (tags_ck1[idx] == tag) {
|
||||||
|
// 将 recent 为设置为 1
|
||||||
|
info[idx] |= 0b1;
|
||||||
|
return;
|
||||||
|
} else if (tags_ck2[idx] == tag) {
|
||||||
|
// 将 recent 为设置为 0
|
||||||
|
info[idx] &= ~0b1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 laneaddr = addr << 10 | idx << 5;
|
||||||
|
u32 trans = 0;
|
||||||
|
|
||||||
|
if (info[idx] & 0b1) {
|
||||||
|
// 最近使用块 1
|
||||||
|
// 将块 2 替换下去
|
||||||
|
|
||||||
|
if (info_ck2[idx] & 0b1) {
|
||||||
|
u32 oldlaneaddr = tags_ck2[idx] << 10 | idx << 5;
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
trans = mem_ck2[idx][i];
|
||||||
|
sysbus->write32(trans, oldlaneaddr);
|
||||||
|
oldlaneaddr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags_ck2[idx] = tag;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
sysbus->read32(trans, laneaddr);
|
||||||
|
mem_ck2[idx][i] = trans;
|
||||||
|
laneaddr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 recent 为设置为 0
|
||||||
|
info[idx] &= ~0b1;
|
||||||
|
} else {
|
||||||
|
// 最近使用块 2
|
||||||
|
// 将块 1 替换下去
|
||||||
|
|
||||||
|
if (info_ck1[idx] & 0b1) {
|
||||||
|
u32 oldlaneaddr = tags_ck1[idx] << 10 | idx << 5;
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
trans = mem_ck1[idx][i];
|
||||||
|
sysbus->write32(trans, oldlaneaddr);
|
||||||
|
oldlaneaddr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags_ck1[idx] = tag;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
sysbus->read32(trans, laneaddr);
|
||||||
|
mem_ck1[idx][i] = trans;
|
||||||
|
laneaddr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 recent 为设置为 1
|
||||||
|
info[idx] |= 0b1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Registers {
|
class Registers {
|
||||||
private:
|
private:
|
||||||
u32 regs_[31] = {0};
|
u32 regs_[31] = {0};
|
||||||
@@ -165,6 +425,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 &operator[](u32 idx) {
|
u32 &operator[](u32 idx) {
|
||||||
|
_ = 0;
|
||||||
panicifnot(0 <= idx && 32 >= idx);
|
panicifnot(0 <= idx && 32 >= idx);
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
return _;
|
return _;
|
||||||
|
|||||||
Reference in New Issue
Block a user