📄 board_pxa_lubbock.cpp
字号:
/*
* Copyright (c) 2005 Zhejiang University, P.R.China
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//=============================================================================
/**
* \file Arch/ARM/Board_PXA_Lubbock.cpp
*
* $Id: Board_PXA_Lubbock.cpp,v 1.2 2005/06/16 11:26:03 qilj Exp $
*
* \author Lingjie Qi <lingjie_qi@163.com>
*/
//=============================================================================
#include "./Board_PXA_Lubbock.h"
#include "Processor_XScale.h"
#include "Core/System.h"
#include "Core/Memory.h"
#include "Core/Helper.h"
#include "Core/ConfigFile.h"
#include "Device/FFUART/FFUART.h"
#include <cstdio>
#include <fstream>
#include "iostream"
#include<io.h>
namespace ARM
{
bool Board_PXA_Lubbock::load_fs(std::string name, Core::u32 addr)
{
std::string filepath = Core::Host_Machine::gen_fullpath(Core::Host_Machine::get_image_path("ARM"), name);
std::ifstream fs((const char *)filepath.c_str(), std::ios::binary);
if (fs.fail())
{
return false;
}
Core::Bytecode_Type buffer;
char ch;
while(fs.get(ch))
{
buffer.push_back(ch);
}
CPU_XScale *cpu = (CPU_XScale *)Core::Wukong_Get_System().get_cpu();
cpu->get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, addr, buffer.size(), buffer);
return true;
}
void Board_PXA_Lubbock::on_reset()
{
uart_ = (Core::Device<Core::u32> *) (Core::Wukong_Get_System().get_device("FFUART"));
WUKONG_ASSERT(uart_ != NULL);
cpu_ = (CPU_XScale *)Core::Wukong_Get_System().get_cpu();
WUKONG_ASSERT(cpu_ != NULL);
mmu_ = &((Core::MMU<Core::u32> &)cpu_->get_mmu());
WUKONG_ASSERT(mmu_ != NULL);
io_prescale_ = FF_SCALE;
cpu_->set_exp_priority(CPU_XScale::CPU_Interrupt::NO_exp);
//! set all Extern_Signal false
for(size_t i=0; i<Board_PXA_Lubbock::Signal_End; ++i)
{
signal_[i] = 0;
}
//! clear all RTC Register's value into 0
for(size_t i=0; i<Board_PXA_Lubbock::RTC_REG_END; ++i)
{
rtc_reg_[i] = 0;
}
//! clear all OS Timer Register's value into 0
for(size_t i=0; i<Board_PXA_Lubbock::OSTimer_REG_END; ++i)
{
ostimer_reg_[i] = 0;
}
//! clear all Interrupt Controller Register's value into 0
for(size_t i=0; i<Board_PXA_Lubbock::IC_REG_END; ++i)
{
ic_reg_[i] = 0;
}
//! clear all Clocks Manager Register's value into 0
for(size_t i=0; i<Board_PXA_Lubbock::CM_REG_END; ++i)
{
cm_reg_[i] = 0;
}
cm_reg_[CCCR] = 0x121;
cm_reg_[CKEN] = 0x17def;
rt_scale = RT_SCALE;
rt_count = 0;
os_scale = OS_SCALE;
}
void Board_PXA_Lubbock::on_destroy()
{
if(uart_ != NULL)
delete uart_;
}
bool Board_PXA_Lubbock::prepare_rom(void)
{
std::string arch_name = Core::Wukong_Get_System().get_arch_name();
std::string conf_file = Core::Wukong_Get_System().get_conf_name();
std::string kernel_name = "";
Core::u32 kernel_addr = 0;
std::string fs_name = "";
Core::u32 fs_addr = 0;
Core::Wukong_Get_System().load_config(arch_name, conf_file);
Core::Config_File * cf = Core::Wukong_Get_System().get_config();
cf->read("/kernel/name", kernel_name);
cf->read("/kernel/address", kernel_addr);
cf->read("/filesystem/name", fs_name);
cf->read("/filesystem/address", fs_addr);
load_fs(fs_name, fs_addr);
return true;
}
void Board_PXA_Lubbock::on_create()
{
name_ = "PXA_Lubbock(XScale_PXA)";
Core::Board<Core::u32>::on_create();
}
Core::Memory_Result Board_PXA_Lubbock::io_dispatch(Core::Memory_Access_Type type, Core::u32 start, \
size_t size, Core::Bytecode_Type & buffer)
{
switch(type)
{
case Core::Memory_32Bit::MEMORY_READ:
return io_read_word(start, size, buffer);
case Core::Memory_32Bit::MEMORY_WRITE:
return io_write_word(start, size, buffer);
default:
return Core::Dummy_MMU<Core::u32>::MEMORY_ACCESS_VIOLATION;
}
}
Core::Memory_Result Board_PXA_Lubbock::io_read_word(Core::u32 start, size_t size, \
Core::Bytecode_Type & buffer)
{
if(start >=0x40000000 && start <= 0x4c000000)
{
Core::u32 target ;
switch(start)
{
/*RTC*/
case 0x40900000: //RCNR
Core::Wukong_Get_System().convert_to_bytecode(rtc_reg_[RCNR], buffer);
break;
case 0x40900004: //RTAR
Core::Wukong_Get_System().convert_to_bytecode(rtc_reg_[RTAR], buffer);
break;
case 0x40900008: //RTSR
Core::Wukong_Get_System().convert_to_bytecode(rtc_reg_[RTSR], buffer);
break;
case 0x4090000C: //RTTR
Core::Wukong_Get_System().convert_to_bytecode(rtc_reg_[RTTR], buffer);
break;
/*OS timer*/
case 0x40A00010: //OSCR
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OSCR], buffer);
break;
case 0x40A00000: //OSMR0
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OSMR0], buffer);
break;
case 0x40A00004: //OSMR1
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OSMR1], buffer);
break;
case 0x40A00008: //OSMR2
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OSMR2], buffer);
break;
case 0x40A0000C: //OSMR3
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OSMR3], buffer);
break;
case 0x40A00018: //OWER
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OWER], buffer);
break;
case 0x40A00014: //OSSR
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OSSR], buffer);
break;
case 0x40A0001C: //OIER
Core::Wukong_Get_System().convert_to_bytecode(ostimer_reg_[OIER], buffer);
break;
/*interrupt controler*/
case 0x40D00010: //Interrupt Controller Pending register (ICPR)
Core::Wukong_Get_System().convert_to_bytecode(ic_reg_[ICPR], buffer);
break;
case 0x40D00000: //Interrupt Controller IRQ Pending register (ICIP)
target = (ic_reg_[ICMR] & ic_reg_[ICPR]) & ~ic_reg_[ICLR];
Core::Wukong_Get_System().convert_to_bytecode(target, buffer);
break;
case 0x40D0000C: //Interrupt Controller FIQ Pending register (ICFP)
target = (ic_reg_[ICMR] & ic_reg_[ICPR]) & ic_reg_[ICLR];
Core::Wukong_Get_System().convert_to_bytecode(target, buffer);
break;
case 0x40D00004: //Interrupt Controller Mask register (ICMR)
Core::Wukong_Get_System().convert_to_bytecode(ic_reg_[ICMR], buffer);
break;
case 0x40D00008: //Interrupt Controller Level register (ICLR)
Core::Wukong_Get_System().convert_to_bytecode(ic_reg_[ICLR], buffer);
break;
/* ffuart control */
case 0x40100000: //FFRBR
case 0x40100004: //FFIER
case 0x40100008: //FFIIR //read only
case 0x4010000C: //FFLCR
case 0x40100014: //FFLSR //read only
uart_->on_mapped_memory_read(start, size, buffer);
break;
// core clock
case 0x41300000: //CCCR
Core::Wukong_Get_System().convert_to_bytecode(cm_reg_[CCCR], buffer);
break;
case 0x41300004: //CKEN
Core::Wukong_Get_System().convert_to_bytecode(cm_reg_[CKEN], buffer);
break;
case 0x41300008: //OSCC
Core::Wukong_Get_System().convert_to_bytecode(cm_reg_[OSCC], buffer);
break;
default:
return Core::Dummy_MMU<Core::u32>::MEMORY_IO_RW;
}
}
else
{
return Core::Dummy_MMU<Core::u32>::MEMORY_IO_RW;
}
return Core::Dummy_MMU<Core::u32>::MEMORY_SUCCESSFUL;
}
Core::Memory_Result Board_PXA_Lubbock::io_write_word(Core::u32 start, size_t size, Core::Bytecode_Type & buffer)
{
if(start >=0x40000000 && start <= 0x4c000000)
{
Core::u32 target = 0;
Core::Wukong_Get_System().convert_from_bytecode(buffer, target);
switch(start)
{
/*RTC*/
case 0x40900000: //RCNR
rtc_reg_[RCNR] = target;
break;
case 0x40900004: //RTAR
rtc_reg_[RTAR] = target;
break;
case 0x40900008: //RTSR
// set HZ interrupt and RTC alarm interrupt by target
rtc_reg_[RTSR] |= (target & 0xc);
// update HZ and AL bits
rtc_reg_[RTSR] &= ~(target & 0x3);
break;
case 0x4090000C: //RTTR
rtc_reg_[RTTR] = target & 0x3ffffff;
break;
/*OS timer*/
case 0x40A00010: //OSCR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -