📄 board_ep7312.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_EP7312.cpp
*
* $Id: Board_EP7312.cpp,v 1.4 2005/06/16 11:26:48 qilj Exp $
*
* \author Lingjie Qi <lingjie_qi@163.com>
zhao jun <junzhao_china@yahoo.com.cn>
*/
//=============================================================================
#include "./Board_EP7312.h"
#include "Processor_720T.h"
#include "Core/System.h"
#include "Core/Memory.h"
#include "Core/Helper.h"
#include "Core/ConfigFile.h"
#include "Device/UART_EP7312/UART_EP7312.h"
#include "Device/LCDDevice/LCD_Device.h"
#include <cstdio>
#include <fstream>
#include "iostream"
#include<io.h>
#include "Core/Observer.h"
namespace ARM
{
bool Board_EP7312::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_720T *cpu = (CPU_720T *)Core::Wukong_Get_System().get_cpu();
cpu->get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, addr, buffer.size(), buffer);
return true;
}
void Board_EP7312::on_reset()
{
uart_ = (Core::Device<Core::u32> *) (Core::Wukong_Get_System().get_device("UART_EP7312"));
WUKONG_ASSERT(uart_ != NULL);
cpu_ = (CPU_720T *)Core::Wukong_Get_System().get_cpu();
WUKONG_ASSERT(cpu_ != NULL);
mmu_ = &((Core::MMU<Core::u32> &)cpu_->get_mmu());
WUKONG_ASSERT(mmu_ != NULL);
lcd_ = (Core::Device<Core::u32> *) (Core::Wukong_Get_System().get_device("LCD_"));
//WUKONG_ASSERT(lcd_ != NULL);
clock = 0xFFFF;
io_prescale_ = 50;
cpu_->set_exp_priority(CPU_720T::CPU_Interrupt::NO_exp);
for(size_t i=0; i<Board_EP7312::Signal_End; ++i)
{
signal_[i] = 0;
}
int_reg_[INTSR1] = 0x1000; // UART transmit FIFO empty interrupt
int_reg_[INTMR1] = 0;
sys_reg_[SYSCON1] = 0;
sys_reg_[SYSFLG1] = 0x00400000; // UART receiver FIFO empty
is_kb_input_ = false;
tcd[0] = tcd [1] =0xfff;
tcd_reload[0] = tcd_reload[1] = 0xfff;
tc_prescale = 50;
}
void Board_EP7312::on_destroy()
{
if(uart_ != NULL)
delete uart_;
}
bool Board_EP7312::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 = "";
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("/filesystem/name", fs_name);
cf->read("/filesystem/address", fs_addr);
load_fs(fs_name, fs_addr);
return true;
}
void Board_EP7312::on_create()
{
name_ = "EP7312(ARM720T)";
Core::Board<Core::u32>::on_create();
}
Core::Memory_Result Board_EP7312::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_EP7312::io_read_word(Core::u32 start, size_t size, \
Core::Bytecode_Type & buffer)
{
if(start >= 0x80000100 && start <= 0x80000840)
{
Core::u32 & uartdr = ((DEVICE::UART_EP7312 *)uart_)->get_uartdr() ;
switch(start)
{
case 0x80000100: // SYSCON1
Core::Wukong_Get_System().convert_to_bytecode(sys_reg_[SYSCON1], buffer);
break;
case 0x80000140: // SYSFLG1
Core::Wukong_Get_System().convert_to_bytecode(sys_reg_[SYSFLG1], buffer);
break;
case 0x80000240: // INTSR1
Core::Wukong_Get_System().convert_to_bytecode(int_reg_[INTSR1], buffer);
break;
case 0x80000280: // INTMR1
Core::Wukong_Get_System().convert_to_bytecode(int_reg_[INTMR1], buffer);
break;
case 0x800002c0: // LCDCON
Core::Wukong_Get_System().convert_to_bytecode(lcd_reg_[LCDCON], buffer);
break;
case 0x80000300: // TC1D
Core::Wukong_Get_System().convert_to_bytecode(tcd[0], buffer);
break;
case 0x80000340: // TC2D
Core::Wukong_Get_System().convert_to_bytecode(tcd[1], buffer);
break;
case 0x80000480: // UARTDR1
Core::Wukong_Get_System().convert_to_bytecode(uartdr, buffer);
sys_reg_[SYSFLG1] |= 0x00400000;
int_reg_[INTSR1] &= ~ 0x2000;
set_external_interrupt();
break;
case 0x80000500: // SYNCIO
Core::Wukong_Get_System().convert_to_bytecode((Core::u32)1, buffer);
break;
// ! write-only
case 0x800005c0: //STFCLR
case 0x80000600: //BLEOI
case 0x80000640: //MCEOI
case 0x80000680: // TEOI
case 0x800006c0: // TC1EOI
case 0x80000700: // TC2EOI
case 0x80000740: // RTCEOI
case 0x80000780: // UMSEOI
case 0x800007c0: // COEOI
case 0x80000800: // HALT
case 0x80000840: // STDBY
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_EP7312::io_write_word(Core::u32 start, size_t size, Core::Bytecode_Type & buffer)
{
if(start >= 0x80000100 && start <= 0x80000700)
{
Core::u32 target = 0;
Core::Wukong_Get_System().convert_from_bytecode(buffer, target);
switch(start)
{
case 0x80000100: // SYSCON1
sys_reg_[SYSCON1] = target;
break;
case 0x80000140: // SYSFLG1
break;
case 0x80000240: // INTSR1
int_reg_[INTSR1] = target;
break;
case 0x80000280: // INTMR1
int_reg_[INTMR1] = target;
set_external_interrupt();
break;
case 0x800002c0: // LCDCON
Core::u32 temp;
temp = lcd_reg_[LCDCON];
lcd_reg_[LCDCON] = target;
if ( temp != target)
{
int width=0, height=0, depth=8;
Core::u32 lcdcon = lcd_reg_[LCDCON];
Core::u32 vbufsiz = lcdcon & VBUFSIZ;
Core::u32 linelen = (lcdcon & LINELEN) >> LINELEN_SHIFT;
width = (linelen + 1) * 16;
height = (vbufsiz + 1) * 128 / depth / width;
//compute_lcd(width, height, depth);
Core::Observer * lcd_screen = Core::Wukong_Get_System().get_view_by_name("LCD_");
lcd_screen ->enable(width,height,depth);
((DEVICE::LCD *)lcd_)->init_lcd(width, height, depth);
((DEVICE::LCD *)lcd_)->malloc_fb(width*height);
lcd_->set_addr(0xc0000000, 0xc0000000+ width*height*depth/8 -1);
lcd_->set_enable(true);
//((DEVICE::LCD *)lcd_)->set_addr(0xc0000000, 0xc0000000+ width*height*depth/8 -1);
//((DEVICE::LCD *)lcd_)->set_enable(true);
// std::cout << "fb_size = " << fb_size << std::endl;
}
break;
case 0x80000300: // TC1D
tcd[0] = tcd_reload[0] = target & 0xfff;
break;
case 0x80000340: // TC2D
tcd[1] = tcd_reload[1] = target & 0xfff;
break;
case 0x80000480: // UARTDR1
uart_->on_mapped_memory_write(start, size, buffer);
break;
case 0x800006c0: // TC1EOI
int_reg_[INTSR1] &= ~0x100;
set_external_interrupt();
break;
case 0x80000700: // TC2EOI
int_reg_[INTSR1] &= ~0x200;
set_external_interrupt();
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;
}
void Board_EP7312::io_do_cycle(void)
{
descend_io_prescale();
if(test_io_prescale())
{
Core::u32 & uartdr = ((DEVICE::UART_EP7312 *)uart_)->get_uartdr();
reset_io_prescale();
if(is_kb_input())
{
is_kb_input_ = true;
char buf;
Core::s32 n = kb_read(0, &buf, 1);
if (n)
{
uartdr = (Core::u32)buf;
}
}
}
}
Core::Interrupt_Type Board_EP7312::get_highest_interrupt(void)
{
descend_clock();
if(is_kb_input_)
{
is_kb_input_ = false;
return Board_EP7312::UXINT_sig;
}
else if( tc_prescale == 0 )
{
reset_clock();
return Board_EP7312::CLOCK_INT;
}
else
{
//clock--;
set_signal(Board_EP7312::IRQ_sig, false);
return Inter_Undefined;
}
}
void Board_EP7312::on_interrupt(Core::Interrupt_Type type)
{
int t;
switch(type)
{
case Board_EP7312::CLOCK_INT:
for (t = 0; t < 2; t++)
{
if (tcd[t] == 0)
{
if (sys_reg_[SYSCON1] & (t ? 0x40 : 0x10))
{
tcd[t] = tcd_reload[t];
} else
{
tcd[t] = 0xffff;
}
int_reg_[INTSR1] |= (t ? 0x200 : 0x100);
if(int_reg_[INTMR1] >> 8 ||int_reg_[INTMR1] >> 9 )
signal_[IRQ_sig] = true;
} else
{
tcd[t]--;
}
}
break;
case Board_EP7312::UXINT_sig:
sys_reg_[SYSFLG1] &= ~0x00400000;
int_reg_[INTSR1] |= 0x2000;
if(int_reg_[INTMR1] >> 13)
signal_[IRQ_sig] = true;
break;
default:
// signal_[IRQ_sig] = false;
break;
}
}
void Board_EP7312::poll_extern_exception()
{
Core::Register &cpsr = cpu_->get_cpsr();
CPU_720T::CPU_Interrupt current_exp_priority = cpu_->get_exp_priority();
if(current_exp_priority > 3 || current_exp_priority < 0)
{
if( test_signal(Board_EP7312::FIQ_sig) \
&& !cpsr.test(6) )
{
cpu_->do_exception(CPU_720T::FIQ_exp);
set_signal(Board_EP7312::FIQ_sig, false);
}
}
if(current_exp_priority > 4 || current_exp_priority < 0)
{
if( test_signal(Board_EP7312::IRQ_sig) \
&& !cpsr.test(7) )
{
cpu_->do_exception(CPU_720T::IRQ_exp);
set_signal(Board_EP7312::IRQ_sig, false);
}
}
}
#ifdef LINUX
Core::s32 Board_EP7312::kb_input()
{
fd_set rfds;
struct timeval tv;
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
return select(0+1, &rfds, NULL, NULL, &tv) ;
}
#endif
#ifdef WIN32
Core::s32 Board_EP7312::kb_read(Core::s32 fd,char *buffer, Core::s32 count)
{
size_t size = Core::Wukong_Get_System().get_key_event_count();
if (size == 0)
return 0;
for (size_t i = 0; (i < size) &&( i < count); ++i)
{
Core::System::Key_Event evt = Core::Wukong_Get_System().top_key_event();
Core::Wukong_Get_System().pop_key_event();
buffer[i] = (char)evt.keycode;
if( buffer[i] == '\r')
buffer[i] = '\n';
}
return i;
/*Core::u32 i;
for( i = 0; (i< count) && kbhit(); i++)
{
// WUKONG_STDOUT<<"_"<<std::endl;
buffer[i] = getch();
//buffer[i] = fgetc(stdin);
if( buffer[i] == '\r')
buffer[i] = '\n';
}
return i;*/
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -