<commit_before>/* $Id$ */

/* @file
 * Tsunami UART
 */

/*
 * Copyright (C) 1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * Copyright (C) 1998 Digital Equipment Corporation
 *
 * This file is part of the SimOS distribution.
 * See LICENSE file for terms of the license.
 *
 */

#include <string>
#include <vector>

#include "base/inifile.hh"
#include "base/str.hh"	// for to_number
#include "base/trace.hh"
#include "dev/console.hh"
#include "dev/tsunami_uart.hh"
#include "mem/functional_mem/memory_control.hh"
#include "sim/builder.hh"
#include "targetarch/ev5.hh"

using namespace std;

#define CONS_INT_TX   0x01  // interrupt enable / state bits
#define CONS_INT_RX   0x02

TsunamiUart::TsunamiUart(const string &name, SimConsole *c,
                       Addr addr, Addr mask, MemoryController *mmu)
    : MmapDevice(name, addr, mask, mmu),
      cons(c), status_store(0), next_char(-1)
{
}

Fault
TsunamiUart::read(MemReqPtr req, uint8_t *data)
{
    Addr daddr = req->paddr & addr_mask;

    switch (req->size) {
      case sizeof(uint64_t):
        *(uint64_t *)data = 0;
        break;
      case sizeof(uint32_t):
        *(uint32_t *)data = 0;
        break;
      case sizeof(uint16_t):
        *(uint16_t *)data = 0;
        break;
      case sizeof(uint8_t):
        *(uint8_t *)data = 0;
        break;
    }

    switch (daddr) {
      case 0xD: // Status Register
        {
            int status = cons->intStatus();
            if (next_char < 0) {
                next_char = cons->in();
                if (next_char < 0) {
                    status &= ~CONS_INT_RX;
                }
            } else {
                status |= CONS_INT_RX;
            }

            if (status_store == 3) {
                // RR3 stuff? Don't really understand it, btw
                status_store = 0;
                if (status & CONS_INT_TX) {
                    *data = (1 << 4);
                    return No_Fault;
                } else if (status & CONS_INT_RX) {
                    *data = (1 << 5);
                    return No_Fault;
                } else {
                    DPRINTF(TsunamiUart, "spurious read\n");
                    return No_Fault;
                }
            } else {
                int reg = (1 << 2);
                if (status & CONS_INT_RX)
                    reg |= (1 << 0);
                *data = reg;
                return No_Fault;
            }
            break;
        }

      case 0x8: // Data register (RX)
        if (next_char < 0)
            panic("Invalid character");

        DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n",
                isprint(next_char) ? next_char : ' ', next_char);

        *data = next_char;
        next_char = -1;
//    cons.next();
        return No_Fault;
    }

    panic("%s: read daddr=%#x type=read *data=%#x\n", name(), daddr, *data);

    return No_Fault;
}

Fault
TsunamiUart::write(MemReqPtr req, const uint8_t *data)
{
    Addr daddr = req->paddr & addr_mask;
    switch (daddr) {
      case 0xb:
        status_store = *data;
        switch (*data) {
          case 0x03: // going to read RR3
            return No_Fault;

          case 0x28: // Ack of TX
            {
                if ((cons->intStatus() & CONS_INT_TX) == 0)
                    panic("Ack of transmit, though there was no interrupt");

                cons->clearInt(CONS_INT_TX);
                return No_Fault;
            }

          case 0x00:
          case 0x01:
          case 0x12:
            // going to write data???
            return No_Fault;

          default:
            DPRINTF(TsunamiUart, "writing status register %#x \n",
                    *(uint64_t *)data);
            return No_Fault;
        }

      case 0x8: // Data register (TX)
        cons->out(*(uint64_t *)data);
        return No_Fault;
      case 0x9: // DLM
        DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint64_t*)data);
        return No_Fault;
      case 0xc: // MCR
        DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint64_t*)data);
        return No_Fault;

    }

    return No_Fault;
}

void
TsunamiUart::serialize(ostream &os)
{
    SERIALIZE_SCALAR(status_store);
    SERIALIZE_SCALAR(next_char);
}

void
TsunamiUart::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_SCALAR(status_store);
    UNSERIALIZE_SCALAR(next_char);
}

BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart)
<commit_msg>uart works in linux<commit_after>/* $Id$ */

/* @file
 * Tsunami UART
 */

/*
 * Copyright (C) 1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * Copyright (C) 1998 Digital Equipment Corporation
 *
 * This file is part of the SimOS distribution.
 * See LICENSE file for terms of the license.
 *
 */

#include <string>
#include <vector>

#include "base/inifile.hh"
#include "base/str.hh"	// for to_number
#include "base/trace.hh"
#include "dev/console.hh"
#include "dev/tsunami_uart.hh"
#include "mem/functional_mem/memory_control.hh"
#include "sim/builder.hh"
#include "targetarch/ev5.hh"

using namespace std;

#define CONS_INT_TX   0x01  // interrupt enable / state bits
#define CONS_INT_RX   0x02

TsunamiUart::TsunamiUart(const string &name, SimConsole *c,
                       Addr addr, Addr mask, MemoryController *mmu)
    : MmapDevice(name, addr, mask, mmu),
      cons(c), status_store(0), next_char(-1)
{
}

Fault
TsunamiUart::read(MemReqPtr req, uint8_t *data)
{
    Addr daddr = req->paddr & addr_mask;
    DPRINTF(TsunamiUart, " read register %#x\n", daddr);

    switch (req->size) {
      case sizeof(uint64_t):
        *(uint64_t *)data = 0;
        break;
      case sizeof(uint32_t):
        *(uint32_t *)data = 0;
        break;
      case sizeof(uint16_t):
        *(uint16_t *)data = 0;
        break;
      case sizeof(uint8_t):
        *(uint8_t *)data = 0;
        break;
    }

    switch (daddr) {
      case 0xD: // Status Register
        {
            int status = cons->intStatus();
            if (next_char < 0) {
                next_char = cons->in();
                if (next_char < 0) {
                    status &= ~CONS_INT_RX;
                }
            } else {
                status |= CONS_INT_RX;
            }

            if (status_store == 3) {
                // RR3 stuff? Don't really understand it, btw
                status_store = 0;
                if (status & CONS_INT_TX) {
                    *data = (1 << 4);
                    return No_Fault;
                } else if (status & CONS_INT_RX) {
                    *data = (1 << 5);
                    return No_Fault;
                } else {
                    DPRINTF(TsunamiUart, "spurious read\n");
                    return No_Fault;
                }
            } else {
                int reg = (1 << 2) | (1 << 5) | (1 << 6);
                if (status & CONS_INT_RX)
                    reg |= (1 << 0);
                *data = reg;
                return No_Fault;
            }
            break;
        }

      case 0x8: // Data register (RX)
        if (next_char < 0)
            panic("Invalid character");

        DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n",
                isprint(next_char) ? next_char : ' ', next_char);

        *data = next_char;
        next_char = -1;
//    cons.next();
        return No_Fault;
      case 0x9: // Interrupt Enable Register
        *data = 0;
        return No_Fault;
    }

    panic("%s: read daddr=%#x type=read *data=%#x\n", name(), daddr, *data);

    return No_Fault;
}

Fault
TsunamiUart::write(MemReqPtr req, const uint8_t *data)
{
    Addr daddr = req->paddr & addr_mask;

    DPRINTF(TsunamiUart, " write register %#x value %#x\n", daddr, *(uint8_t*)data);
    switch (daddr) {
      case 0xb:
        status_store = *data;
        switch (*data) {
          case 0x03: // going to read RR3
            return No_Fault;

          case 0x28: // Ack of TX
            {
                if ((cons->intStatus() & CONS_INT_TX) == 0)
                    panic("Ack of transmit, though there was no interrupt");

                cons->clearInt(CONS_INT_TX);
                return No_Fault;
            }

          case 0x00:
          case 0x01:
          case 0x12:
            // going to write data???
            return No_Fault;

          default:
            DPRINTF(TsunamiUart, "writing status register %#x \n",
                    *(uint64_t *)data);
            return No_Fault;
        }

      case 0x8: // Data register (TX)
        cons->out(*(uint64_t *)data);
        return No_Fault;
      case 0x9: // DLM
        DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data);
        return No_Fault;
      case 0xc: // MCR
        DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint8_t*)data);
        return No_Fault;

    }

    return No_Fault;
}

void
TsunamiUart::serialize(ostream &os)
{
    SERIALIZE_SCALAR(status_store);
    SERIALIZE_SCALAR(next_char);
}

void
TsunamiUart::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_SCALAR(status_store);
    UNSERIALIZE_SCALAR(next_char);
}

BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart)

{'fraction_non_alphanumeric': 0.11955574912891986, 'fraction_numerical': 0.019817073170731708, 'mean_word_length': 1.7070439139404656, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2927850', 'n_tokens_mistral': 3245, 'n_tokens_neox': 2981, 'n_words': 735}