Fixed serial support in 2.6 (too much work for...)
Removed bootloader and just wrote command line into linux kernel base/inifile.cc: the forked process should not return, it should exit. dev/tsunami_uart.cc: dev/tsunami_uart.hh: The serial port in reality has some delay and linux expects it. This schedules an interrupt 300 cycles after the transmit instead of immediately kern/linux/linux_system.cc: kern/linux/linux_system.hh: removed boot loader and stuck boot command line in the kernel manually --HG-- extra : convert_revision : 68aa54f8ca4e8391789f7a4c1ae227e6f8b94e13
This commit is contained in:
parent
f0d45c797c
commit
fffae72b45
5 changed files with 103 additions and 63 deletions
|
@ -142,7 +142,7 @@ IniFile::loadCPP(const string &file, vector<char *> &cppArgs)
|
||||||
|
|
||||||
close(STDOUT_FILENO);
|
close(STDOUT_FILENO);
|
||||||
if (dup2(fd[1], STDOUT_FILENO) == -1)
|
if (dup2(fd[1], STDOUT_FILENO) == -1)
|
||||||
return 1;
|
exit(1);
|
||||||
|
|
||||||
execvp("g++", args);
|
execvp("g++", args);
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,48 @@ using namespace std;
|
||||||
#define CONS_INT_TX 0x01 // interrupt enable / state bits
|
#define CONS_INT_TX 0x01 // interrupt enable / state bits
|
||||||
#define CONS_INT_RX 0x02
|
#define CONS_INT_RX 0x02
|
||||||
|
|
||||||
|
|
||||||
|
TsunamiUart::IntrEvent::IntrEvent(TsunamiUart *u)
|
||||||
|
: Event(&mainEventQueue), uart(u)
|
||||||
|
{
|
||||||
|
DPRINTF(TsunamiUart, "UART Interrupt Event Initilizing\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
TsunamiUart::IntrEvent::description()
|
||||||
|
{
|
||||||
|
return "tsunami uart interrupt delay event";
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TsunamiUart::IntrEvent::process()
|
||||||
|
{
|
||||||
|
if (UART_IER_THRI & uart->IER) {
|
||||||
|
DPRINTF(TsunamiUart, "UART InterEvent, interrupting\n");
|
||||||
|
uart->cons->raiseInt(CONS_INT_TX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DPRINTF(TsunamiUart, "UART InterEvent, not interrupting\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TsunamiUart::IntrEvent::scheduleIntr()
|
||||||
|
{
|
||||||
|
DPRINTF(TsunamiUart, "Scheduling IER interrupt\n");
|
||||||
|
if (!scheduled())
|
||||||
|
schedule(curTick + 300);
|
||||||
|
else
|
||||||
|
reschedule(curTick + 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TsunamiUart::TsunamiUart(const string &name, SimConsole *c,
|
TsunamiUart::TsunamiUart(const string &name, SimConsole *c,
|
||||||
MemoryController *mmu, Addr a,
|
MemoryController *mmu, Addr a,
|
||||||
HierParams *hier, Bus *bus)
|
HierParams *hier, Bus *bus)
|
||||||
: PioDevice(name), addr(a), cons(c), status_store(0), valid_char(false)
|
: PioDevice(name), addr(a), cons(c), status_store(0), valid_char(false),
|
||||||
|
intrEvent(this)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, Range<Addr>(addr, addr + size));
|
mmu->add_child(this, Range<Addr>(addr, addr + size));
|
||||||
|
|
||||||
|
@ -108,9 +146,6 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x0: // Data register (RX)
|
case 0x0: // Data register (RX)
|
||||||
// if (!valid_char)
|
|
||||||
// panic("Invalid character");
|
|
||||||
|
|
||||||
DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n",
|
DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n",
|
||||||
isprint(next_char) ? next_char : ' ', next_char);
|
isprint(next_char) ? next_char : ' ', next_char);
|
||||||
|
|
||||||
|
@ -129,7 +164,11 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data)
|
||||||
*data = 0;
|
*data = 0;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
*data = 0; // This means a 8250 serial port, do we want a 16550?
|
// High two bits need to be clear for an 8250 (simple) serial port
|
||||||
|
// Low bit of IIR is 0 for a pending interrupt, 1 otherwise.
|
||||||
|
int status = cons->intStatus();
|
||||||
|
status = (status & 0x1) | (status >> 1);
|
||||||
|
*data = (~status) & 0x1 ;
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
}
|
}
|
||||||
*data = 0;
|
*data = 0;
|
||||||
|
@ -178,15 +217,20 @@ TsunamiUart::write(MemReqPtr &req, const uint8_t *data)
|
||||||
ourchar = *(uint64_t *)data;
|
ourchar = *(uint64_t *)data;
|
||||||
if ((isprint(ourchar) || iscntrl(ourchar)) && (ourchar != 0x0C))
|
if ((isprint(ourchar) || iscntrl(ourchar)) && (ourchar != 0x0C))
|
||||||
cons->out(ourchar);
|
cons->out(ourchar);
|
||||||
if (UART_IER_THRI & IER)
|
cons->clearInt(CONS_INT_TX);
|
||||||
cons->setInt(CONS_INT_TX);
|
intrEvent.scheduleIntr();
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
break;
|
break;
|
||||||
case 0x1: // DLM
|
case 0x1: // IER
|
||||||
DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data);
|
|
||||||
IER = *(uint8_t*)data;
|
IER = *(uint8_t*)data;
|
||||||
|
DPRINTF(TsunamiUart, "writing to IER [%#x]\n", IER);
|
||||||
if (UART_IER_THRI & IER)
|
if (UART_IER_THRI & IER)
|
||||||
cons->setInt(CONS_INT_TX);
|
cons->raiseInt(CONS_INT_TX);
|
||||||
|
else {
|
||||||
|
cons->clearInt(CONS_INT_TX);
|
||||||
|
if (intrEvent.scheduled())
|
||||||
|
intrEvent.deschedule();
|
||||||
|
}
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
break;
|
break;
|
||||||
case 0x4: // MCR
|
case 0x4: // MCR
|
||||||
|
|
|
@ -48,6 +48,7 @@ class TsunamiUart : public PioDevice
|
||||||
Addr addr;
|
Addr addr;
|
||||||
static const Addr size = 0x8;
|
static const Addr size = 0x8;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SimConsole *cons;
|
SimConsole *cons;
|
||||||
int status_store;
|
int status_store;
|
||||||
|
@ -55,6 +56,19 @@ class TsunamiUart : public PioDevice
|
||||||
bool valid_char;
|
bool valid_char;
|
||||||
uint8_t IER;
|
uint8_t IER;
|
||||||
|
|
||||||
|
class IntrEvent : public Event
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
TsunamiUart *uart;
|
||||||
|
public:
|
||||||
|
IntrEvent(TsunamiUart *u);
|
||||||
|
virtual void process();
|
||||||
|
virtual const char *description();
|
||||||
|
void scheduleIntr();
|
||||||
|
};
|
||||||
|
|
||||||
|
IntrEvent intrEvent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TsunamiUart(const string &name, SimConsole *c, MemoryController *mmu,
|
TsunamiUart(const string &name, SimConsole *c, MemoryController *mmu,
|
||||||
Addr a, HierParams *hier, Bus *bus);
|
Addr a, HierParams *hier, Bus *bus);
|
||||||
|
|
|
@ -51,40 +51,23 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
||||||
MemoryController *_memCtrl, PhysicalMemory *_physmem,
|
MemoryController *_memCtrl, PhysicalMemory *_physmem,
|
||||||
const string &kernel_path, const string &console_path,
|
const string &kernel_path, const string &console_path,
|
||||||
const string &palcode, const string &boot_osflags,
|
const string &palcode, const string &boot_osflags,
|
||||||
const string &bootloader_path, const bool _bin,
|
const bool _bin, const vector<string> &_binned_fns)
|
||||||
const vector<string> &_binned_fns)
|
|
||||||
: System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns),
|
: System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns),
|
||||||
bin(_bin), binned_fns(_binned_fns)
|
bin(_bin), binned_fns(_binned_fns)
|
||||||
{
|
{
|
||||||
kernelSymtab = new SymbolTable;
|
kernelSymtab = new SymbolTable;
|
||||||
consoleSymtab = new SymbolTable;
|
consoleSymtab = new SymbolTable;
|
||||||
bootloaderSymtab = new SymbolTable;
|
|
||||||
|
|
||||||
|
// Load kernel code
|
||||||
ObjectFile *kernel = createObjectFile(kernel_path);
|
ObjectFile *kernel = createObjectFile(kernel_path);
|
||||||
if (kernel == NULL)
|
if (kernel == NULL)
|
||||||
fatal("Could not load kernel file %s", kernel_path);
|
fatal("Could not load kernel file %s", kernel_path);
|
||||||
|
|
||||||
|
// Load Console Code
|
||||||
ObjectFile *console = createObjectFile(console_path);
|
ObjectFile *console = createObjectFile(console_path);
|
||||||
if (console == NULL)
|
if (console == NULL)
|
||||||
fatal("Could not load console file %s", console_path);
|
fatal("Could not load console file %s", console_path);
|
||||||
|
|
||||||
ObjectFile *bootloader = createObjectFile(bootloader_path);
|
|
||||||
if (bootloader == NULL)
|
|
||||||
fatal("Could not load bootloader file %s", bootloader_path);
|
|
||||||
|
|
||||||
if (!kernel->loadGlobalSymbols(kernelSymtab))
|
|
||||||
panic("could not load kernel symbols\n");
|
|
||||||
debugSymbolTable = kernelSymtab;
|
|
||||||
|
|
||||||
if (!kernel->loadLocalSymbols(kernelSymtab))
|
|
||||||
panic("could not load kernel local symbols\n");
|
|
||||||
|
|
||||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
|
||||||
panic("could not load console symbols\n");
|
|
||||||
|
|
||||||
if (!bootloader->loadGlobalSymbols(bootloaderSymtab))
|
|
||||||
panic("could not load bootloader symbols\n");
|
|
||||||
|
|
||||||
// Load pal file
|
// Load pal file
|
||||||
ObjectFile *pal = createObjectFile(palcode);
|
ObjectFile *pal = createObjectFile(palcode);
|
||||||
if (pal == NULL)
|
if (pal == NULL)
|
||||||
|
@ -98,10 +81,18 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
||||||
kernel->loadSections(physmem, true);
|
kernel->loadSections(physmem, true);
|
||||||
kernelStart = kernel->textBase();
|
kernelStart = kernel->textBase();
|
||||||
kernelEnd = kernel->bssBase() + kernel->bssSize();
|
kernelEnd = kernel->bssBase() + kernel->bssSize();
|
||||||
/* FIXME: entrypoint not in kernel, but in bootloader,
|
|
||||||
variable should be re-named appropriately */
|
|
||||||
kernelEntry = kernel->entryPoint();
|
kernelEntry = kernel->entryPoint();
|
||||||
|
|
||||||
|
// load symbols
|
||||||
|
if (!kernel->loadGlobalSymbols(kernelSymtab))
|
||||||
|
panic("could not load kernel symbols\n");
|
||||||
|
debugSymbolTable = kernelSymtab;
|
||||||
|
|
||||||
|
if (!kernel->loadLocalSymbols(kernelSymtab))
|
||||||
|
panic("could not load kernel local symbols\n");
|
||||||
|
|
||||||
|
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||||
|
panic("could not load console symbols\n");
|
||||||
|
|
||||||
DPRINTF(Loader, "Kernel start = %#x\n"
|
DPRINTF(Loader, "Kernel start = %#x\n"
|
||||||
"Kernel end = %#x\n"
|
"Kernel end = %#x\n"
|
||||||
|
@ -110,11 +101,6 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
||||||
|
|
||||||
DPRINTF(Loader, "Kernel loaded...\n");
|
DPRINTF(Loader, "Kernel loaded...\n");
|
||||||
|
|
||||||
// Load bootloader file
|
|
||||||
bootloader->loadSections(physmem, true);
|
|
||||||
kernelEntry = bootloader->entryPoint();
|
|
||||||
kernelStart = bootloader->textBase();
|
|
||||||
DPRINTF(Loader, "Bootloader entry at %#x\n", kernelEntry);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
|
kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
|
||||||
|
@ -140,15 +126,6 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
||||||
*(uint64_t *)est_cycle_frequency = ticksPerSecond;
|
*(uint64_t *)est_cycle_frequency = ticksPerSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kernelSymtab->findAddress("aic7xxx_no_reset", addr)) {
|
|
||||||
Addr paddr = vtophys(physmem, addr);
|
|
||||||
uint8_t *aic7xxx_no_reset =
|
|
||||||
physmem->dma_addr(paddr, sizeof(uint32_t));
|
|
||||||
|
|
||||||
if (aic7xxx_no_reset) {
|
|
||||||
*(uint32_t *)aic7xxx_no_reset = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
||||||
Addr paddr = vtophys(physmem, addr);
|
Addr paddr = vtophys(physmem, addr);
|
||||||
|
@ -158,6 +135,14 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
||||||
strcpy(osflags, boot_osflags.c_str());
|
strcpy(osflags, boot_osflags.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Addr paddr = vtophys(physmem, PARAM_ADDR);
|
||||||
|
char *commandline = (char*)physmem->dma_addr(paddr, sizeof(uint64_t));
|
||||||
|
if (commandline)
|
||||||
|
strcpy(commandline, boot_osflags.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (consoleSymtab->findAddress("xxm_rpb", addr)) {
|
if (consoleSymtab->findAddress("xxm_rpb", addr)) {
|
||||||
Addr paddr = vtophys(physmem, addr);
|
Addr paddr = vtophys(physmem, addr);
|
||||||
char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
|
char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
|
||||||
|
@ -199,7 +184,6 @@ LinuxSystem::~LinuxSystem()
|
||||||
|
|
||||||
delete kernelSymtab;
|
delete kernelSymtab;
|
||||||
delete consoleSymtab;
|
delete consoleSymtab;
|
||||||
delete bootloaderSymtab;
|
|
||||||
|
|
||||||
delete kernelPanicEvent;
|
delete kernelPanicEvent;
|
||||||
delete consolePanicEvent;
|
delete consolePanicEvent;
|
||||||
|
@ -208,6 +192,7 @@ LinuxSystem::~LinuxSystem()
|
||||||
delete skipCacheProbeEvent;
|
delete skipCacheProbeEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LinuxSystem::setDelayLoop(ExecContext *xc)
|
LinuxSystem::setDelayLoop(ExecContext *xc)
|
||||||
{
|
{
|
||||||
|
@ -275,7 +260,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
|
||||||
Param<string> console_code;
|
Param<string> console_code;
|
||||||
Param<string> pal_code;
|
Param<string> pal_code;
|
||||||
Param<string> boot_osflags;
|
Param<string> boot_osflags;
|
||||||
Param<string> bootloader_code;
|
|
||||||
VectorParam<string> binned_fns;
|
VectorParam<string> binned_fns;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
|
END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
|
||||||
|
@ -292,7 +276,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
|
||||||
INIT_PARAM(pal_code, "file that contains palcode"),
|
INIT_PARAM(pal_code, "file that contains palcode"),
|
||||||
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||||
"a"),
|
"a"),
|
||||||
INIT_PARAM(bootloader_code, "file that contains the bootloader"),
|
|
||||||
INIT_PARAM(binned_fns, "functions to be broken down and binned")
|
INIT_PARAM(binned_fns, "functions to be broken down and binned")
|
||||||
|
|
||||||
|
|
||||||
|
@ -302,8 +285,7 @@ CREATE_SIM_OBJECT(LinuxSystem)
|
||||||
{
|
{
|
||||||
LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl,
|
LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl,
|
||||||
physmem, kernel_code, console_code,
|
physmem, kernel_code, console_code,
|
||||||
pal_code, boot_osflags, bootloader_code,
|
pal_code, boot_osflags, bin, binned_fns);
|
||||||
bin, binned_fns);
|
|
||||||
|
|
||||||
return sys;
|
return sys;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,13 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
#include "sim/host.hh"
|
||||||
#include "targetarch/isa_traits.hh"
|
#include "targetarch/isa_traits.hh"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
const Addr PARAM_ADDR = ULL(0xfffffc000030a000);
|
||||||
|
|
||||||
class ExecContext;
|
class ExecContext;
|
||||||
class ElfObject;
|
class ElfObject;
|
||||||
class SymbolTable;
|
class SymbolTable;
|
||||||
|
@ -55,10 +58,8 @@ class LinuxSystem : public System
|
||||||
private:
|
private:
|
||||||
ElfObject *kernel;
|
ElfObject *kernel;
|
||||||
ElfObject *console;
|
ElfObject *console;
|
||||||
ElfObject *bootloader;
|
|
||||||
|
|
||||||
SymbolTable *kernelSymtab;
|
SymbolTable *kernelSymtab;
|
||||||
SymbolTable *bootloaderSymtab;
|
|
||||||
SymbolTable *consoleSymtab;
|
SymbolTable *consoleSymtab;
|
||||||
|
|
||||||
BreakPCEvent *kernelPanicEvent;
|
BreakPCEvent *kernelPanicEvent;
|
||||||
|
@ -88,7 +89,6 @@ class LinuxSystem : public System
|
||||||
const std::string &console_path,
|
const std::string &console_path,
|
||||||
const std::string &palcode,
|
const std::string &palcode,
|
||||||
const std::string &boot_osflags,
|
const std::string &boot_osflags,
|
||||||
const std::string &bootloader_path,
|
|
||||||
const bool _bin,
|
const bool _bin,
|
||||||
const std::vector<std::string> &_binned_fns);
|
const std::vector<std::string> &_binned_fns);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue