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

📄 ppc405_uc.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* * QEMU PowerPC 405 embedded processors emulation * * Copyright (c) 2007 Jocelyn Mayer * * 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 "ppc.h"#include "ppc405.h"#include "pc.h"#include "qemu-timer.h"#include "sysemu.h"extern int loglevel;extern FILE *logfile;#define DEBUG_OPBA#define DEBUG_SDRAM#define DEBUG_GPIO#define DEBUG_SERIAL#define DEBUG_OCM//#define DEBUG_I2C#define DEBUG_GPT#define DEBUG_MAL#define DEBUG_CLOCKS//#define DEBUG_CLOCKS_LLram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,                                uint32_t flags){    ram_addr_t bdloc;    int i, n;    /* We put the bd structure at the top of memory */    if (bd->bi_memsize >= 0x01000000UL)        bdloc = 0x01000000UL - sizeof(struct ppc4xx_bd_info_t);    else        bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t);    stl_raw(phys_ram_base + bdloc + 0x00, bd->bi_memstart);    stl_raw(phys_ram_base + bdloc + 0x04, bd->bi_memsize);    stl_raw(phys_ram_base + bdloc + 0x08, bd->bi_flashstart);    stl_raw(phys_ram_base + bdloc + 0x0C, bd->bi_flashsize);    stl_raw(phys_ram_base + bdloc + 0x10, bd->bi_flashoffset);    stl_raw(phys_ram_base + bdloc + 0x14, bd->bi_sramstart);    stl_raw(phys_ram_base + bdloc + 0x18, bd->bi_sramsize);    stl_raw(phys_ram_base + bdloc + 0x1C, bd->bi_bootflags);    stl_raw(phys_ram_base + bdloc + 0x20, bd->bi_ipaddr);    for (i = 0; i < 6; i++)        stb_raw(phys_ram_base + bdloc + 0x24 + i, bd->bi_enetaddr[i]);    stw_raw(phys_ram_base + bdloc + 0x2A, bd->bi_ethspeed);    stl_raw(phys_ram_base + bdloc + 0x2C, bd->bi_intfreq);    stl_raw(phys_ram_base + bdloc + 0x30, bd->bi_busfreq);    stl_raw(phys_ram_base + bdloc + 0x34, bd->bi_baudrate);    for (i = 0; i < 4; i++)        stb_raw(phys_ram_base + bdloc + 0x38 + i, bd->bi_s_version[i]);    for (i = 0; i < 32; i++)        stb_raw(phys_ram_base + bdloc + 0x3C + i, bd->bi_s_version[i]);    stl_raw(phys_ram_base + bdloc + 0x5C, bd->bi_plb_busfreq);    stl_raw(phys_ram_base + bdloc + 0x60, bd->bi_pci_busfreq);    for (i = 0; i < 6; i++)        stb_raw(phys_ram_base + bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]);    n = 0x6A;    if (flags & 0x00000001) {        for (i = 0; i < 6; i++)            stb_raw(phys_ram_base + bdloc + n++, bd->bi_pci_enetaddr2[i]);    }    stl_raw(phys_ram_base + bdloc + n, bd->bi_opbfreq);    n += 4;    for (i = 0; i < 2; i++) {        stl_raw(phys_ram_base + bdloc + n, bd->bi_iic_fast[i]);        n += 4;    }    return bdloc;}/*****************************************************************************//* Shared peripherals *//*****************************************************************************//* Peripheral local bus arbitrer */enum {    PLB0_BESR = 0x084,    PLB0_BEAR = 0x086,    PLB0_ACR  = 0x087,};typedef struct ppc4xx_plb_t ppc4xx_plb_t;struct ppc4xx_plb_t {    uint32_t acr;    uint32_t bear;    uint32_t besr;};static target_ulong dcr_read_plb (void *opaque, int dcrn){    ppc4xx_plb_t *plb;    target_ulong ret;    plb = opaque;    switch (dcrn) {    case PLB0_ACR:        ret = plb->acr;        break;    case PLB0_BEAR:        ret = plb->bear;        break;    case PLB0_BESR:        ret = plb->besr;        break;    default:        /* Avoid gcc warning */        ret = 0;        break;    }    return ret;}static void dcr_write_plb (void *opaque, int dcrn, target_ulong val){    ppc4xx_plb_t *plb;    plb = opaque;    switch (dcrn) {    case PLB0_ACR:        /* We don't care about the actual parameters written as         * we don't manage any priorities on the bus         */        plb->acr = val & 0xF8000000;        break;    case PLB0_BEAR:        /* Read only */        break;    case PLB0_BESR:        /* Write-clear */        plb->besr &= ~val;        break;    }}static void ppc4xx_plb_reset (void *opaque){    ppc4xx_plb_t *plb;    plb = opaque;    plb->acr = 0x00000000;    plb->bear = 0x00000000;    plb->besr = 0x00000000;}void ppc4xx_plb_init (CPUState *env){    ppc4xx_plb_t *plb;    plb = qemu_mallocz(sizeof(ppc4xx_plb_t));    if (plb != NULL) {        ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);        ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);        ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);        ppc4xx_plb_reset(plb);        qemu_register_reset(ppc4xx_plb_reset, plb);    }}/*****************************************************************************//* PLB to OPB bridge */enum {    POB0_BESR0 = 0x0A0,    POB0_BESR1 = 0x0A2,    POB0_BEAR  = 0x0A4,};typedef struct ppc4xx_pob_t ppc4xx_pob_t;struct ppc4xx_pob_t {    uint32_t bear;    uint32_t besr[2];};static target_ulong dcr_read_pob (void *opaque, int dcrn){    ppc4xx_pob_t *pob;    target_ulong ret;    pob = opaque;    switch (dcrn) {    case POB0_BEAR:        ret = pob->bear;        break;    case POB0_BESR0:    case POB0_BESR1:        ret = pob->besr[dcrn - POB0_BESR0];        break;    default:        /* Avoid gcc warning */        ret = 0;        break;    }    return ret;}static void dcr_write_pob (void *opaque, int dcrn, target_ulong val){    ppc4xx_pob_t *pob;    pob = opaque;    switch (dcrn) {    case POB0_BEAR:        /* Read only */        break;    case POB0_BESR0:    case POB0_BESR1:        /* Write-clear */        pob->besr[dcrn - POB0_BESR0] &= ~val;        break;    }}static void ppc4xx_pob_reset (void *opaque){    ppc4xx_pob_t *pob;    pob = opaque;    /* No error */    pob->bear = 0x00000000;    pob->besr[0] = 0x0000000;    pob->besr[1] = 0x0000000;}void ppc4xx_pob_init (CPUState *env){    ppc4xx_pob_t *pob;    pob = qemu_mallocz(sizeof(ppc4xx_pob_t));    if (pob != NULL) {        ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob);        ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob);        ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob);        qemu_register_reset(ppc4xx_pob_reset, pob);        ppc4xx_pob_reset(env);    }}/*****************************************************************************//* OPB arbitrer */typedef struct ppc4xx_opba_t ppc4xx_opba_t;struct ppc4xx_opba_t {    target_phys_addr_t base;    uint8_t cr;    uint8_t pr;};static uint32_t opba_readb (void *opaque, target_phys_addr_t addr){    ppc4xx_opba_t *opba;    uint32_t ret;#ifdef DEBUG_OPBA    printf("%s: addr " PADDRX "\n", __func__, addr);#endif    opba = opaque;    switch (addr - opba->base) {    case 0x00:        ret = opba->cr;        break;    case 0x01:        ret = opba->pr;        break;    default:        ret = 0x00;        break;    }    return ret;}static void opba_writeb (void *opaque,                         target_phys_addr_t addr, uint32_t value){    ppc4xx_opba_t *opba;#ifdef DEBUG_OPBA    printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif    opba = opaque;    switch (addr - opba->base) {    case 0x00:        opba->cr = value & 0xF8;        break;    case 0x01:        opba->pr = value & 0xFF;        break;    default:        break;    }}static uint32_t opba_readw (void *opaque, target_phys_addr_t addr){    uint32_t ret;#ifdef DEBUG_OPBA    printf("%s: addr " PADDRX "\n", __func__, addr);#endif    ret = opba_readb(opaque, addr) << 8;    ret |= opba_readb(opaque, addr + 1);    return ret;}static void opba_writew (void *opaque,                         target_phys_addr_t addr, uint32_t value){#ifdef DEBUG_OPBA    printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif    opba_writeb(opaque, addr, value >> 8);    opba_writeb(opaque, addr + 1, value);}static uint32_t opba_readl (void *opaque, target_phys_addr_t addr){    uint32_t ret;#ifdef DEBUG_OPBA    printf("%s: addr " PADDRX "\n", __func__, addr);#endif    ret = opba_readb(opaque, addr) << 24;    ret |= opba_readb(opaque, addr + 1) << 16;    return ret;}static void opba_writel (void *opaque,                         target_phys_addr_t addr, uint32_t value){#ifdef DEBUG_OPBA    printf("%s: addr " PADDRX " val %08" PRIx32 "\n", __func__, addr, value);#endif    opba_writeb(opaque, addr, value >> 24);    opba_writeb(opaque, addr + 1, value >> 16);}static CPUReadMemoryFunc *opba_read[] = {    &opba_readb,    &opba_readw,    &opba_readl,};static CPUWriteMemoryFunc *opba_write[] = {    &opba_writeb,    &opba_writew,    &opba_writel,};static void ppc4xx_opba_reset (void *opaque){    ppc4xx_opba_t *opba;    opba = opaque;    opba->cr = 0x00; /* No dynamic priorities - park disabled */    opba->pr = 0x11;}void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio,                       target_phys_addr_t offset){    ppc4xx_opba_t *opba;    opba = qemu_mallocz(sizeof(ppc4xx_opba_t));    if (opba != NULL) {        opba->base = offset;#ifdef DEBUG_OPBA        printf("%s: offset " PADDRX "\n", __func__, offset);#endif        ppc4xx_mmio_register(env, mmio, offset, 0x002,                             opba_read, opba_write, opba);        qemu_register_reset(ppc4xx_opba_reset, opba);        ppc4xx_opba_reset(opba);    }}/*****************************************************************************//* Code decompression controller *//* XXX: TODO *//*****************************************************************************//* SDRAM controller */typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;struct ppc4xx_sdram_t {    uint32_t addr;    int nbanks;    target_phys_addr_t ram_bases[4];    target_phys_addr_t ram_sizes[4];    uint32_t besr0;    uint32_t besr1;    uint32_t bear;    uint32_t cfg;    uint32_t status;    uint32_t rtr;    uint32_t pmit;    uint32_t bcr[4];    uint32_t tr;    uint32_t ecccfg;    uint32_t eccesr;    qemu_irq irq;};enum {    SDRAM0_CFGADDR = 0x010,    SDRAM0_CFGDATA = 0x011,};/* XXX: TOFIX: some patches have made this code become inconsistent: *      there are type inconsistencies, mixing target_phys_addr_t, target_ulong *      and uint32_t */static uint32_t sdram_bcr (target_phys_addr_t ram_base,                           target_phys_addr_t ram_size){    uint32_t bcr;    switch (ram_size) {    case (4 * 1024 * 1024):        bcr = 0x00000000;        break;    case (8 * 1024 * 1024):        bcr = 0x00020000;        break;    case (16 * 1024 * 1024):        bcr = 0x00040000;        break;    case (32 * 1024 * 1024):        bcr = 0x00060000;        break;    case (64 * 1024 * 1024):        bcr = 0x00080000;        break;    case (128 * 1024 * 1024):        bcr = 0x000A0000;        break;    case (256 * 1024 * 1024):        bcr = 0x000C0000;        break;    default:        printf("%s: invalid RAM size " PADDRX "\n", __func__, ram_size);        return 0x00000000;    }    bcr |= ram_base & 0xFF800000;    bcr |= 1;    return bcr;}static always_inline target_phys_addr_t sdram_base (uint32_t bcr){    return bcr & 0xFF800000;}static target_ulong sdram_size (uint32_t bcr){    target_ulong size;    int sh;    sh = (bcr >> 17) & 0x7;    if (sh == 7)        size = -1;    else        size = (4 * 1024 * 1024) << sh;    return size;}static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled){    if (*bcrp & 0x00000001) {        /* Unmap RAM */#ifdef DEBUG_SDRAM        printf("%s: unmap RAM area " PADDRX " " ADDRX "\n",               __func__, sdram_base(*bcrp), sdram_size(*bcrp));#endif        cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),                                     IO_MEM_UNASSIGNED);    }    *bcrp = bcr & 0xFFDEE001;    if (enabled && (bcr & 0x00000001)) {#ifdef DEBUG_SDRAM        printf("%s: Map RAM area " PADDRX " " ADDRX "\n",

⌨️ 快捷键说明

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