⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mips_malta.c

📁 QEMU 0.91 source code, supports ARM processor including S3C24xx series
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * QEMU Malta board support * * Copyright (c) 2006 Aurelien Jarno * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */#include "hw.h"#include "pc.h"#include "fdc.h"#include "net.h"#include "boards.h"#include "smbus.h"#include "block.h"#include "flash.h"#include "mips.h"#include "pci.h"#include "qemu-char.h"#include "sysemu.h"#include "audio/audio.h"#include "boards.h"//#define DEBUG_BOARD_INIT#ifdef TARGET_WORDS_BIGENDIAN#define BIOS_FILENAME "mips_bios.bin"#else#define BIOS_FILENAME "mipsel_bios.bin"#endif#ifdef TARGET_MIPS64#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)#else#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)#endif#define ENVP_ADDR (int32_t)0x80002000#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))#define ENVP_NB_ENTRIES	 	16#define ENVP_ENTRY_SIZE	 	256#define MAX_IDE_BUS 2extern FILE *logfile;typedef struct {    uint32_t leds;    uint32_t brk;    uint32_t gpout;    uint32_t i2cin;    uint32_t i2coe;    uint32_t i2cout;    uint32_t i2csel;    CharDriverState *display;    char display_text[9];    SerialState *uart;} MaltaFPGAState;static PITState *pit;static struct _loaderparams {    int ram_size;    const char *kernel_filename;    const char *kernel_cmdline;    const char *initrd_filename;} loaderparams;/* Malta FPGA */static void malta_fpga_update_display(void *opaque){    char leds_text[9];    int i;    MaltaFPGAState *s = opaque;    for (i = 7 ; i >= 0 ; i--) {        if (s->leds & (1 << i))            leds_text[i] = '#';        else            leds_text[i] = ' ';    }    leds_text[8] = '\0';    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);}/* * EEPROM 24C01 / 24C02 emulation. * * Emulation for serial EEPROMs: * 24C01 - 1024 bit (128 x 8) * 24C02 - 2048 bit (256 x 8) * * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02. *///~ #define DEBUG#if defined(DEBUG)#  define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)#else#  define logout(fmt, args...) ((void)0)#endifstruct _eeprom24c0x_t {  uint8_t tick;  uint8_t address;  uint8_t command;  uint8_t ack;  uint8_t scl;  uint8_t sda;  uint8_t data;  //~ uint16_t size;  uint8_t contents[256];};typedef struct _eeprom24c0x_t eeprom24c0x_t;static eeprom24c0x_t eeprom = {    contents: {        /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,        /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,        /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,        /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,        /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,        /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,        /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,        /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,    },};static uint8_t eeprom24c0x_read(){    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);    return eeprom.sda;}static void eeprom24c0x_write(int scl, int sda){    if (eeprom.scl && scl && (eeprom.sda != sda)) {        logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");        if (!sda) {            eeprom.tick = 1;            eeprom.command = 0;        }    } else if (eeprom.tick == 0 && !eeprom.ack) {        /* Waiting for start. */        logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);    } else if (!eeprom.scl && scl) {        logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);        if (eeprom.ack) {            logout("\ti2c ack bit = 0\n");            sda = 0;            eeprom.ack = 0;        } else if (eeprom.sda == sda) {            uint8_t bit = (sda != 0);            logout("\ti2c bit = %d\n", bit);            if (eeprom.tick < 9) {                eeprom.command <<= 1;                eeprom.command += bit;                eeprom.tick++;                if (eeprom.tick == 9) {                    logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");                    eeprom.ack = 1;                }            } else if (eeprom.tick < 17) {                if (eeprom.command & 1) {                    sda = ((eeprom.data & 0x80) != 0);                }                eeprom.address <<= 1;                eeprom.address += bit;                eeprom.tick++;                eeprom.data <<= 1;                if (eeprom.tick == 17) {                    eeprom.data = eeprom.contents[eeprom.address];                    logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);                    eeprom.ack = 1;                    eeprom.tick = 0;                }            } else if (eeprom.tick >= 17) {                sda = 0;            }        } else {            logout("\tsda changed with raising scl\n");        }    } else {        logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);    }    eeprom.scl = scl;    eeprom.sda = sda;}static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr){    MaltaFPGAState *s = opaque;    uint32_t val = 0;    uint32_t saddr;    saddr = (addr & 0xfffff);    switch (saddr) {    /* SWITCH Register */    case 0x00200:        val = 0x00000000;		/* All switches closed */	break;    /* STATUS Register */    case 0x00208:#ifdef TARGET_WORDS_BIGENDIAN        val = 0x00000012;#else        val = 0x00000010;#endif        break;    /* JMPRS Register */    case 0x00210:        val = 0x00;        break;    /* LEDBAR Register */    case 0x00408:        val = s->leds;        break;    /* BRKRES Register */    case 0x00508:        val = s->brk;        break;    /* UART Registers are handled directly by the serial device */    /* GPOUT Register */    case 0x00a00:        val = s->gpout;        break;    /* XXX: implement a real I2C controller */    /* GPINP Register */    case 0x00a08:        /* IN = OUT until a real I2C control is implemented */        if (s->i2csel)            val = s->i2cout;        else            val = 0x00;        break;    /* I2CINP Register */    case 0x00b00:        val = ((s->i2cin & ~1) | eeprom24c0x_read());        break;    /* I2COE Register */    case 0x00b08:        val = s->i2coe;        break;    /* I2COUT Register */    case 0x00b10:        val = s->i2cout;        break;    /* I2CSEL Register */    case 0x00b18:        val = s->i2csel;        break;    default:#if 0        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",		addr);#endif        break;    }    return val;}static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,                              uint32_t val){    MaltaFPGAState *s = opaque;    uint32_t saddr;    saddr = (addr & 0xfffff);    switch (saddr) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -