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
|
@ -142,7 +142,7 @@ IniFile::loadCPP(const string &file, vector<char *> &cppArgs)
|
|||
|
||||
close(STDOUT_FILENO);
|
||||
if (dup2(fd[1], STDOUT_FILENO) == -1)
|
||||
return 1;
|
||||
exit(1);
|
||||
|
||||
execvp("g++", args);
|
||||
|
||||
|
|
|
@ -34,10 +34,48 @@ using namespace std;
|
|||
#define CONS_INT_TX 0x01 // interrupt enable / state bits
|
||||
#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,
|
||||
MemoryController *mmu, Addr a,
|
||||
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));
|
||||
|
||||
|
@ -74,14 +112,14 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data)
|
|||
|
||||
switch(daddr) {
|
||||
case 0x5: // Status Register
|
||||
{
|
||||
{
|
||||
int status = cons->intStatus();
|
||||
if (!valid_char) {
|
||||
valid_char = cons->in(next_char);
|
||||
valid_char = cons->in(next_char);
|
||||
if (!valid_char)
|
||||
status &= ~CONS_INT_RX;
|
||||
} else {
|
||||
status |= CONS_INT_RX;
|
||||
status |= CONS_INT_RX;
|
||||
}
|
||||
|
||||
if (status_store == 3) {
|
||||
|
@ -101,18 +139,15 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data)
|
|||
int reg = (1 << 2) | (1 << 5) | (1 << 6);
|
||||
if (status & CONS_INT_RX)
|
||||
reg |= (1 << 0);
|
||||
*data = reg;
|
||||
return No_Fault;
|
||||
*data = reg;
|
||||
return No_Fault;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 0x0: // Data register (RX)
|
||||
// if (!valid_char)
|
||||
// panic("Invalid character");
|
||||
|
||||
DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n",
|
||||
isprint(next_char) ? next_char : ' ', next_char);
|
||||
isprint(next_char) ? next_char : ' ', next_char);
|
||||
|
||||
*data = next_char;
|
||||
valid_char = false;
|
||||
|
@ -129,7 +164,11 @@ TsunamiUart::read(MemReqPtr &req, uint8_t *data)
|
|||
*data = 0;
|
||||
return No_Fault;
|
||||
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;
|
||||
}
|
||||
*data = 0;
|
||||
|
@ -178,15 +217,20 @@ TsunamiUart::write(MemReqPtr &req, const uint8_t *data)
|
|||
ourchar = *(uint64_t *)data;
|
||||
if ((isprint(ourchar) || iscntrl(ourchar)) && (ourchar != 0x0C))
|
||||
cons->out(ourchar);
|
||||
if (UART_IER_THRI & IER)
|
||||
cons->setInt(CONS_INT_TX);
|
||||
cons->clearInt(CONS_INT_TX);
|
||||
intrEvent.scheduleIntr();
|
||||
return No_Fault;
|
||||
break;
|
||||
case 0x1: // DLM
|
||||
DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data);
|
||||
case 0x1: // IER
|
||||
IER = *(uint8_t*)data;
|
||||
DPRINTF(TsunamiUart, "writing to IER [%#x]\n", 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;
|
||||
break;
|
||||
case 0x4: // MCR
|
||||
|
|
|
@ -48,6 +48,7 @@ class TsunamiUart : public PioDevice
|
|||
Addr addr;
|
||||
static const Addr size = 0x8;
|
||||
|
||||
|
||||
protected:
|
||||
SimConsole *cons;
|
||||
int status_store;
|
||||
|
@ -55,6 +56,19 @@ class TsunamiUart : public PioDevice
|
|||
bool valid_char;
|
||||
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:
|
||||
TsunamiUart(const string &name, SimConsole *c, MemoryController *mmu,
|
||||
Addr a, HierParams *hier, Bus *bus);
|
||||
|
|
|
@ -51,40 +51,23 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
|||
MemoryController *_memCtrl, PhysicalMemory *_physmem,
|
||||
const string &kernel_path, const string &console_path,
|
||||
const string &palcode, const string &boot_osflags,
|
||||
const string &bootloader_path, const bool _bin,
|
||||
const vector<string> &_binned_fns)
|
||||
const bool _bin, const vector<string> &_binned_fns)
|
||||
: System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns),
|
||||
bin(_bin), binned_fns(_binned_fns)
|
||||
{
|
||||
kernelSymtab = new SymbolTable;
|
||||
consoleSymtab = new SymbolTable;
|
||||
bootloaderSymtab = new SymbolTable;
|
||||
|
||||
// Load kernel code
|
||||
ObjectFile *kernel = createObjectFile(kernel_path);
|
||||
if (kernel == NULL)
|
||||
fatal("Could not load kernel file %s", kernel_path);
|
||||
|
||||
// Load Console Code
|
||||
ObjectFile *console = createObjectFile(console_path);
|
||||
if (console == NULL)
|
||||
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
|
||||
ObjectFile *pal = createObjectFile(palcode);
|
||||
if (pal == NULL)
|
||||
|
@ -98,10 +81,18 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
|||
kernel->loadSections(physmem, true);
|
||||
kernelStart = kernel->textBase();
|
||||
kernelEnd = kernel->bssBase() + kernel->bssSize();
|
||||
/* FIXME: entrypoint not in kernel, but in bootloader,
|
||||
variable should be re-named appropriately */
|
||||
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"
|
||||
"Kernel end = %#x\n"
|
||||
|
@ -110,11 +101,6 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
|||
|
||||
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
|
||||
kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
|
||||
|
@ -140,24 +126,23 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
|
|||
*(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)) {
|
||||
Addr paddr = vtophys(physmem, addr);
|
||||
char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
|
||||
|
||||
if (osflags)
|
||||
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)) {
|
||||
Addr paddr = vtophys(physmem, addr);
|
||||
char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
|
||||
|
@ -199,7 +184,6 @@ LinuxSystem::~LinuxSystem()
|
|||
|
||||
delete kernelSymtab;
|
||||
delete consoleSymtab;
|
||||
delete bootloaderSymtab;
|
||||
|
||||
delete kernelPanicEvent;
|
||||
delete consolePanicEvent;
|
||||
|
@ -208,6 +192,7 @@ LinuxSystem::~LinuxSystem()
|
|||
delete skipCacheProbeEvent;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinuxSystem::setDelayLoop(ExecContext *xc)
|
||||
{
|
||||
|
@ -275,7 +260,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
|
|||
Param<string> console_code;
|
||||
Param<string> pal_code;
|
||||
Param<string> boot_osflags;
|
||||
Param<string> bootloader_code;
|
||||
VectorParam<string> binned_fns;
|
||||
|
||||
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_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||
"a"),
|
||||
INIT_PARAM(bootloader_code, "file that contains the bootloader"),
|
||||
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,
|
||||
physmem, kernel_code, console_code,
|
||||
pal_code, boot_osflags, bootloader_code,
|
||||
bin, binned_fns);
|
||||
pal_code, boot_osflags, bin, binned_fns);
|
||||
|
||||
return sys;
|
||||
}
|
||||
|
|
|
@ -32,10 +32,13 @@
|
|||
#include <vector>
|
||||
|
||||
#include "sim/system.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "targetarch/isa_traits.hh"
|
||||
|
||||
#include <map>
|
||||
|
||||
const Addr PARAM_ADDR = ULL(0xfffffc000030a000);
|
||||
|
||||
class ExecContext;
|
||||
class ElfObject;
|
||||
class SymbolTable;
|
||||
|
@ -55,10 +58,8 @@ class LinuxSystem : public System
|
|||
private:
|
||||
ElfObject *kernel;
|
||||
ElfObject *console;
|
||||
ElfObject *bootloader;
|
||||
|
||||
SymbolTable *kernelSymtab;
|
||||
SymbolTable *bootloaderSymtab;
|
||||
SymbolTable *consoleSymtab;
|
||||
|
||||
BreakPCEvent *kernelPanicEvent;
|
||||
|
@ -88,7 +89,6 @@ class LinuxSystem : public System
|
|||
const std::string &console_path,
|
||||
const std::string &palcode,
|
||||
const std::string &boot_osflags,
|
||||
const std::string &bootloader_path,
|
||||
const bool _bin,
|
||||
const std::vector<std::string> &_binned_fns);
|
||||
|
||||
|
|
Loading…
Reference in a new issue