mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-01-31 01:11:07 +02:00
split off nanonote code, try to make it boot
This commit is contained in:
parent
36d830e801
commit
d0287820e6
4
.gitignore
vendored
4
.gitignore
vendored
@ -3,9 +3,13 @@ iris.raw
|
|||||||
iris.raw.gz
|
iris.raw.gz
|
||||||
uimage
|
uimage
|
||||||
*.o
|
*.o
|
||||||
|
*.elf
|
||||||
*.cc
|
*.cc
|
||||||
*.hh
|
*.hh
|
||||||
gpio
|
gpio
|
||||||
lcd
|
lcd
|
||||||
init
|
init
|
||||||
|
udc
|
||||||
boot-programs/charset.data
|
boot-programs/charset.data
|
||||||
|
mips/nanonote/sdram-setup.raw
|
||||||
|
nanonote-boot
|
||||||
|
2
Makefile
2
Makefile
@ -43,7 +43,7 @@ PYPP = /usr/bin/pypp
|
|||||||
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@
|
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
%: boot-programs/crt0.o boot-programs/%.o
|
%: boot-programs/crt0.o boot-programs/%.o
|
||||||
$(LD) $(filter %.o,$^) -o $@
|
$(LD) $(LDFLAGS) $(filter %.o,$^) -o $@
|
||||||
#$(OBJCOPY) -S $(OBJCOPYFLAGS) $@
|
#$(OBJCOPY) -S $(OBJCOPYFLAGS) $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -84,6 +84,8 @@ Kernel::Num start ():
|
|||||||
if code & Keyboard::RELEASE:
|
if code & Keyboard::RELEASE:
|
||||||
break
|
break
|
||||||
kdebug_char (decode_kbd[code])
|
kdebug_char (decode_kbd[code])
|
||||||
|
if code == 0:
|
||||||
|
Kernel::Caps ().print (~0)
|
||||||
break
|
break
|
||||||
case TP:
|
case TP:
|
||||||
unsigned leds = 0
|
unsigned leds = 0
|
||||||
|
@ -32,7 +32,7 @@ struct Init : public Kernel::Cap:
|
|||||||
GPIO_LOCKLEDS
|
GPIO_LOCKLEDS
|
||||||
GPIO_PWM
|
GPIO_PWM
|
||||||
LCD_SET_EOF_CB
|
LCD_SET_EOF_CB
|
||||||
LCD_LOG
|
LOG
|
||||||
void register_gpio ():
|
void register_gpio ():
|
||||||
Kernel::Caps c = Kernel::my_memory.create_caps (4)
|
Kernel::Caps c = Kernel::my_memory.create_caps (4)
|
||||||
unsigned slot = c.use ()
|
unsigned slot = c.use ()
|
||||||
|
@ -40,6 +40,7 @@ struct Descriptor:
|
|||||||
unsigned id
|
unsigned id
|
||||||
unsigned cmd
|
unsigned cmd
|
||||||
|
|
||||||
|
#if defined (TRENDTAC)
|
||||||
static void reset ():
|
static void reset ():
|
||||||
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
|
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
|
||||||
LCD_VSYNC = vs
|
LCD_VSYNC = vs
|
||||||
@ -68,6 +69,12 @@ static void reset ():
|
|||||||
LCD_DA0 = physical_descriptor
|
LCD_DA0 = physical_descriptor
|
||||||
lcd_set_ena ()
|
lcd_set_ena ()
|
||||||
lcd_enable_eof_intr ()
|
lcd_enable_eof_intr ()
|
||||||
|
#elif defined (NANONOTE)
|
||||||
|
static void reset ():
|
||||||
|
// TODO
|
||||||
|
#else
|
||||||
|
#error unknown board
|
||||||
|
#endif
|
||||||
|
|
||||||
static void putchar (unsigned x, unsigned y, unsigned ch, unsigned fg = 0xffff, unsigned bg = 0x0000):
|
static void putchar (unsigned x, unsigned y, unsigned ch, unsigned fg = 0xffff, unsigned bg = 0x0000):
|
||||||
if ch < 32 || ch > 126:
|
if ch < 32 || ch > 126:
|
||||||
@ -163,7 +170,6 @@ Kernel::Num start ():
|
|||||||
|
|
||||||
((Init)Kernel::my_parent).register_lcd ()
|
((Init)Kernel::my_parent).register_lcd ()
|
||||||
|
|
||||||
unsigned slot = Kernel::alloc_slot ()
|
|
||||||
Kernel::Cap eof_cb = Kernel::alloc_cap ()
|
Kernel::Cap eof_cb = Kernel::alloc_cap ()
|
||||||
while true:
|
while true:
|
||||||
Kernel::wait ()
|
Kernel::wait ()
|
||||||
|
317
boot-programs/udc.ccp
Normal file
317
boot-programs/udc.ccp
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
#pypp 0
|
||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// boot-programs/udc.ccp: USB device controller driver.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "devices.hh"
|
||||||
|
#include "init.hh"
|
||||||
|
#define ARCH
|
||||||
|
#include "arch.hh"
|
||||||
|
|
||||||
|
class Udc:
|
||||||
|
typedef unsigned char u8
|
||||||
|
typedef unsigned short u16
|
||||||
|
typedef unsigned int u32
|
||||||
|
typedef u8 string
|
||||||
|
// The ugly stuff is because pypp doesn't support __attribute__.
|
||||||
|
/**/struct Setup {
|
||||||
|
u8 request_type;
|
||||||
|
u8 request;
|
||||||
|
u16 value;
|
||||||
|
u16 index;
|
||||||
|
u16 length;
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
/**/struct Device {
|
||||||
|
static u8 const Type = 1;
|
||||||
|
u8 length;
|
||||||
|
u8 type;
|
||||||
|
u16 usb_version;
|
||||||
|
u8 dev_class;
|
||||||
|
u8 subclass;
|
||||||
|
u8 protocol;
|
||||||
|
u8 max_packet_size0;
|
||||||
|
u16 vendor;
|
||||||
|
u16 product;
|
||||||
|
u16 dev_version;
|
||||||
|
string s_manufacturer;
|
||||||
|
string s_product;
|
||||||
|
string s_serial;
|
||||||
|
u8 num_configurations;
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
/**/struct Configuration {
|
||||||
|
static u8 const Type = 2;
|
||||||
|
u8 length;
|
||||||
|
u8 type;
|
||||||
|
u16 total_length;
|
||||||
|
u8 num_interfaces;
|
||||||
|
u8 configuration_value;
|
||||||
|
u8 configuration;
|
||||||
|
u8 attributes;
|
||||||
|
u8 max_power;
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
/**/struct Interface {
|
||||||
|
static u8 const Type = 4;
|
||||||
|
u8 length;
|
||||||
|
u8 type;
|
||||||
|
u8 interface;
|
||||||
|
u8 alternate;
|
||||||
|
u8 num_endpoints;
|
||||||
|
u8 iface_class;
|
||||||
|
u8 subclass;
|
||||||
|
u8 protocol;
|
||||||
|
string name;
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
/**/struct Endpoint {
|
||||||
|
static u8 const Type = 5;
|
||||||
|
u8 length;
|
||||||
|
u8 type;
|
||||||
|
u8 address;
|
||||||
|
u8 attributes;
|
||||||
|
u16 max_packet_size;
|
||||||
|
u8 interval;
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
template <unsigned size> struct String {
|
||||||
|
static u8 const Type = 3;
|
||||||
|
u8 length;
|
||||||
|
u8 type;
|
||||||
|
u16 data[size];
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
static unsigned const max_packet_size0 = 64
|
||||||
|
static unsigned const max_packet_size_bulk = 512
|
||||||
|
enum Requests:
|
||||||
|
GET_STATUS = 0
|
||||||
|
CLEAR_FEATURE = 1
|
||||||
|
SET_FEATURE = 3
|
||||||
|
SET_ADDRESS = 5
|
||||||
|
GET_DESCRIPTOR = 6
|
||||||
|
SET_DESCRIPTOR = 7
|
||||||
|
GET_CONFIGURATION = 8
|
||||||
|
SET_CONFIGURATION = 9
|
||||||
|
GET_INTERFACE = 10
|
||||||
|
SET_INTERFACE = 11
|
||||||
|
SYNCH_FRAME = 12
|
||||||
|
enum Request_types:
|
||||||
|
STANDARD_TO_DEVICE = 0
|
||||||
|
VENDOR_TO_DEVICE = 0x40
|
||||||
|
STANDARD_FROM_DEVICE = 0x80
|
||||||
|
VENDOR_FROM_DEVICE = 0xc0
|
||||||
|
enum Endpoint_types:
|
||||||
|
CONTROL = 0
|
||||||
|
ISOCHRONOUS = 1
|
||||||
|
BULK = 2
|
||||||
|
INTERRUPT = 3
|
||||||
|
/**/struct my_config {
|
||||||
|
Configuration config;
|
||||||
|
Interface interface;
|
||||||
|
Endpoint endpoint[2];
|
||||||
|
} __attribute__ ((packed))
|
||||||
|
static Device const device_descriptor
|
||||||
|
static my_config const config_descriptor
|
||||||
|
static String <7> const s_manufacturer
|
||||||
|
static String <22> const s_product
|
||||||
|
enum State:
|
||||||
|
IDLE
|
||||||
|
TX
|
||||||
|
RX
|
||||||
|
State state
|
||||||
|
char configuration
|
||||||
|
unsigned size
|
||||||
|
char const *ptr
|
||||||
|
unsigned send_next (unsigned old_csr)
|
||||||
|
unsigned vendor (unsigned old_csr, Setup *s)
|
||||||
|
unsigned get_descriptor (unsigned old_csr, unsigned type, unsigned idx, unsigned len)
|
||||||
|
public:
|
||||||
|
void init ()
|
||||||
|
void log (unsigned c)
|
||||||
|
void interrupt ()
|
||||||
|
unsigned handle_setup (unsigned old_csr, Setup *s)
|
||||||
|
|
||||||
|
Udc::Device const Udc::device_descriptor = { sizeof (Device), Device::Type, 0x200, 0, 0, 0, max_packet_size0, 0x601a, 0x4740, 0x100, 1, 2, 0, 1 }
|
||||||
|
Udc::my_config const Udc::config_descriptor = {
|
||||||
|
(Configuration){ sizeof (Configuration), Configuration::Type, sizeof (my_config), 1, 1, 0, 0xc0, 1 },
|
||||||
|
(Interface){ sizeof (Interface), Interface::Type, 0, 0, 2, 0xff, 0, 0x80, 0 }, {
|
||||||
|
(Endpoint){ sizeof (Endpoint), Endpoint::Type, 1, BULK, max_packet_size_bulk, 0 },
|
||||||
|
(Endpoint){ sizeof (Endpoint), Endpoint::Type, 0x81, BULK, max_packet_size_bulk, 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Udc::String <7> const Udc::s_manufacturer = { sizeof (String <7>), String <7>::Type, { 'I', 'n', 'g', 'e', 'n', 'i', 'c' } }
|
||||||
|
Udc::String <22> const Udc::s_product = { sizeof (String <22>), String <22>::Type, { 'J', 'Z', '4', '7', '4', '0', ' ', 'U', 'S', 'B', ' ', 'B', 'o', 'o', 't', ' ', 'D', 'e', 'v', 'i', 'c', 'e'} }
|
||||||
|
void Udc::init ():
|
||||||
|
state = IDLE
|
||||||
|
configuration = 0
|
||||||
|
size = 0
|
||||||
|
// exit suspend mode by reading the interrupt register.
|
||||||
|
unsigned i = UDC_INTRUSB
|
||||||
|
// reset all pending endpoint interrupts.
|
||||||
|
i = UDC_INTRIN
|
||||||
|
i = UDC_INTROUT
|
||||||
|
// enable interrupt on bus reset.
|
||||||
|
UDC_INTRUSB = UDC_INTR_RESET
|
||||||
|
// enable interrupts on endpoint 0.
|
||||||
|
UDC_INTRINE |= 1 << 0
|
||||||
|
|
||||||
|
unsigned Udc::send_next (unsigned old_csr):
|
||||||
|
for unsigned i = 0; size > 0 && i < max_packet_size0; ++i, --size:
|
||||||
|
// Use 8-bit transfers to avoid problems with alignment.
|
||||||
|
REG8 (UDC_FIFO_EP0) = *ptr++
|
||||||
|
if size:
|
||||||
|
state = TX
|
||||||
|
return (old_csr | UDC_CSR0_INPKTRDY) & ~UDC_CSR0_DATAEND
|
||||||
|
else:
|
||||||
|
state = IDLE
|
||||||
|
return old_csr | UDC_CSR0_INPKTRDY
|
||||||
|
|
||||||
|
unsigned Udc::vendor (unsigned old_csr, Setup *s):
|
||||||
|
if s->request_type & 0x80:
|
||||||
|
ptr = "abcdefgh"
|
||||||
|
size = 8
|
||||||
|
return send_next (old_csr)
|
||||||
|
return old_csr
|
||||||
|
|
||||||
|
unsigned Udc::get_descriptor (unsigned old_csr, unsigned type, unsigned idx, unsigned len):
|
||||||
|
switch type:
|
||||||
|
case Configuration::Type:
|
||||||
|
if idx != 1:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
ptr = reinterpret_cast <char const *> (&config_descriptor)
|
||||||
|
size = (len < sizeof (config_descriptor) ? len : sizeof (config_descriptor))
|
||||||
|
break
|
||||||
|
case Device::Type:
|
||||||
|
if idx != 0:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
ptr = reinterpret_cast <char const *> (&device_descriptor)
|
||||||
|
size = (len < sizeof (device_descriptor) ? len : sizeof (device_descriptor))
|
||||||
|
break
|
||||||
|
// The 7 is an arbitrary number.
|
||||||
|
case String <7>::Type:
|
||||||
|
switch idx:
|
||||||
|
case 1:
|
||||||
|
ptr = reinterpret_cast <char const *> (&s_manufacturer)
|
||||||
|
size = (len < sizeof (s_manufacturer) ? len : sizeof (s_manufacturer))
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
ptr = reinterpret_cast <char const *> (&s_product)
|
||||||
|
size = (len < sizeof (s_product) ? len : sizeof (s_product))
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
return send_next (old_csr)
|
||||||
|
|
||||||
|
unsigned Udc::handle_setup (unsigned old_csr, Setup *s):
|
||||||
|
switch s->request_type:
|
||||||
|
case STANDARD_TO_DEVICE:
|
||||||
|
switch s->request:
|
||||||
|
case SET_ADDRESS:
|
||||||
|
UDC_FADDR = s->value
|
||||||
|
break
|
||||||
|
case SET_CONFIGURATION:
|
||||||
|
if s->value >= 2:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
configuration = s->value
|
||||||
|
break
|
||||||
|
case SET_INTERFACE:
|
||||||
|
if s->value != 0:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
break
|
||||||
|
case STANDARD_FROM_DEVICE:
|
||||||
|
switch s->request:
|
||||||
|
case GET_STATUS:
|
||||||
|
ptr = "\0\0"
|
||||||
|
size = (s->length < 2 ? s->length : 2)
|
||||||
|
return send_next (old_csr)
|
||||||
|
case GET_DESCRIPTOR:
|
||||||
|
return get_descriptor (old_csr, (s->value >> 8) & 0xff, s->value & 0xff, s->length)
|
||||||
|
case GET_CONFIGURATION:
|
||||||
|
ptr = &configuration
|
||||||
|
size = (s->length < 1 ? s->length : 1)
|
||||||
|
return send_next (old_csr)
|
||||||
|
case GET_INTERFACE:
|
||||||
|
ptr = "\0"
|
||||||
|
size = (s->length < 1 ? s->length : 1)
|
||||||
|
return send_next (old_csr)
|
||||||
|
default:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
break
|
||||||
|
case VENDOR_TO_DEVICE:
|
||||||
|
case VENDOR_FROM_DEVICE:
|
||||||
|
return vendor (old_csr, s)
|
||||||
|
default:
|
||||||
|
return old_csr | UDC_CSR0_SENDSTALL
|
||||||
|
return old_csr
|
||||||
|
|
||||||
|
void Udc::interrupt ():
|
||||||
|
unsigned i = UDC_INTRUSB
|
||||||
|
if i & UDC_INTR_RESET:
|
||||||
|
state = IDLE
|
||||||
|
return
|
||||||
|
i = UDC_INTRIN
|
||||||
|
if i & (1 << 0):
|
||||||
|
// Interrupt on endpoint 0.
|
||||||
|
unsigned csr = UDC_CSR0
|
||||||
|
if csr & UDC_CSR0_SENTSTALL:
|
||||||
|
csr &= ~UDC_CSR0_SENTSTALL
|
||||||
|
state = IDLE
|
||||||
|
if csr & UDC_CSR0_SETUPEND:
|
||||||
|
csr |= UDC_CSR0_SVDSETUPEND
|
||||||
|
state = IDLE
|
||||||
|
switch state:
|
||||||
|
case IDLE:
|
||||||
|
if !(csr & UDC_CSR0_OUTPKTRDY):
|
||||||
|
break
|
||||||
|
csr |= UDC_CSR0_SVDOUTPKTRDY | UDC_CSR0_DATAEND
|
||||||
|
union { unsigned d[2]; Setup s; } packet
|
||||||
|
packet.d[0] = UDC_FIFO_EP0
|
||||||
|
packet.d[1] = UDC_FIFO_EP0
|
||||||
|
csr = handle_setup (csr, &packet.s)
|
||||||
|
UDC_CSR0 = csr
|
||||||
|
break
|
||||||
|
case TX:
|
||||||
|
UDC_CSR0 = send_next (UDC_CSR0 | UDC_CSR0_DATAEND)
|
||||||
|
break
|
||||||
|
case RX:
|
||||||
|
// Not supported.
|
||||||
|
UDC_CSR0 |= UDC_CSR0_SENDSTALL
|
||||||
|
state = IDLE
|
||||||
|
break
|
||||||
|
|
||||||
|
void Udc::log (unsigned c):
|
||||||
|
|
||||||
|
Kernel::Num start ():
|
||||||
|
map_udc ()
|
||||||
|
Udc udc
|
||||||
|
|
||||||
|
udc.init ()
|
||||||
|
Kernel::Cap logcap = Kernel::my_receiver.create_capability (Init::LOG)
|
||||||
|
__asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
|
||||||
|
Kernel::register_interrupt (IRQ_UDC)
|
||||||
|
while true:
|
||||||
|
Kernel::wait ()
|
||||||
|
switch Kernel::recv.protected_data.l:
|
||||||
|
case IRQ_UDC:
|
||||||
|
udc.interrupt ()
|
||||||
|
break
|
||||||
|
case Init::LOG:
|
||||||
|
udc.log (Kernel::recv.data[0].l)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
udc.log ('~')
|
||||||
|
break
|
@ -730,6 +730,10 @@ static void caps_invoke (unsigned cmd, unsigned target, Kernel::Num protected_da
|
|||||||
return
|
return
|
||||||
case Kernel::Caps::PRINT & REQUEST_MASK:
|
case Kernel::Caps::PRINT & REQUEST_MASK:
|
||||||
if c->data[1].l >= caps->size:
|
if c->data[1].l >= caps->size:
|
||||||
|
if c->data[1].l == ~0:
|
||||||
|
// debug: power down.
|
||||||
|
*((volatile unsigned *)0xa0003020) = 1
|
||||||
|
return
|
||||||
dpanic (0, "invalid caps for print")
|
dpanic (0, "invalid caps for print")
|
||||||
return
|
return
|
||||||
kCapRef cap (caps, c->data[1].l)
|
kCapRef cap (caps, c->data[1].l)
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
# Iris: micro-kernel for a capability-based operating system.
|
|
||||||
# mips/Makefile.arch: mips-specific parts of the build rules
|
|
||||||
# Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
|
||||||
#
|
|
||||||
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
load = 0x80000000
|
|
||||||
|
|
||||||
ARCH_CXXFLAGS = -DNUM_THREADS=3
|
|
||||||
ARCH_CPPFLAGS = -Imips -Wa,-mips32
|
|
||||||
CROSS = mipsel-linux-gnu-
|
|
||||||
OBJDUMP = $(CROSS)objdump
|
|
||||||
junk = mdebug.abi32 reginfo comment pdr
|
|
||||||
OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
|
||||||
|
|
||||||
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
|
||||||
boot_sources = mips/init.cc
|
|
||||||
arch_headers = mips/arch.hh mips/jz4730.hh
|
|
||||||
boot_threads = init gpio lcd
|
|
||||||
|
|
||||||
uimage:
|
|
||||||
|
|
||||||
mips/entry.o: $(boot_threads)
|
|
||||||
mips/init.o: TARGET_FLAGS = -I/usr/include
|
|
||||||
$(boot_threads): TARGET_FLAGS = -I.
|
|
||||||
$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh boot-programs/init.hh
|
|
||||||
lcd: boot-programs/charset.data
|
|
||||||
|
|
||||||
boot-programs/charset.data: boot-programs/charset
|
|
||||||
$< > $@
|
|
||||||
|
|
||||||
# Transform ':' into ';' so vim doesn't think there are errors.
|
|
||||||
uimage: iris.raw.gz Makefile mips/Makefile.arch
|
|
||||||
mkimage -A MIPS -O Linux -C gzip -a $(load) -e 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris | grep __start$$ | cut -b2-8') -n "Iris" -d $< $@ | sed -e 's/:/;/g'
|
|
||||||
|
|
||||||
%.o:%.S Makefile mips/Makefile.arch mips/arch.hh
|
|
||||||
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@
|
|
||||||
|
|
||||||
# entry.o must be the first file. boot.o must be the first of the init objects (which can be freed after loading).
|
|
||||||
iris: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/boot.o $(subst .cc,.o,$(boot_sources))
|
|
||||||
$(LD) --omagic -Ttext $(load) $^ -o $@
|
|
||||||
|
|
||||||
%.raw: %
|
|
||||||
$(OBJCOPY) -S $(OBJCOPYFLAGS) -Obinary $< $@
|
|
||||||
|
|
||||||
%.gz: %
|
|
||||||
gzip < $< > $@
|
|
||||||
|
|
||||||
ARCH_CLEAN_FILES = uimage $(boot_threads) mips/*.o boot-programs/charset.data iris iris.raw iris.raw.gz
|
|
1
mips/Makefile.arch
Symbolic link
1
mips/Makefile.arch
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
board/Makefile.arch
|
@ -17,7 +17,7 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#define ARCH
|
#define ARCH
|
||||||
#include "../kernel.hh"
|
#include "kernel.hh"
|
||||||
|
|
||||||
void kThread_arch_init (kThread *thread):
|
void kThread_arch_init (kThread *thread):
|
||||||
thread->arch.at = 0
|
thread->arch.at = 0
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#ifdef ARCH
|
#ifdef ARCH
|
||||||
|
|
||||||
#ifndef ASM
|
#ifndef ASM
|
||||||
#include "jz4730.hh"
|
#include "board.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define reg_hack(x...) #x
|
#define reg_hack(x...) #x
|
||||||
@ -131,6 +131,7 @@ extern "C":
|
|||||||
#ifdef INIT
|
#ifdef INIT
|
||||||
// Initialize most things (the rest is done in boot.S)
|
// Initialize most things (the rest is done in boot.S)
|
||||||
void init (unsigned mem)
|
void init (unsigned mem)
|
||||||
|
void board_init ()
|
||||||
// Start running the idle task for the first time.
|
// Start running the idle task for the first time.
|
||||||
void run_idle (kThread *self)
|
void run_idle (kThread *self)
|
||||||
#endif
|
#endif
|
||||||
|
1
mips/board
Symbolic link
1
mips/board
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
nanonote
|
24
mips/boot.S
24
mips/boot.S
@ -1,5 +1,5 @@
|
|||||||
// Iris: micro-kernel for a capability-based operating system.
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
// mips/boot.S: Kernel entry point, called by the boot loader.
|
// mips/trendtac/boot.S: Kernel entry point, called by the boot loader.
|
||||||
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
@ -15,16 +15,16 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#define ASM
|
||||||
|
#define ARCH
|
||||||
|
#include "arch.hh"
|
||||||
|
|
||||||
// The kernel stack.
|
// The kernel stack.
|
||||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
||||||
|
|
||||||
.globl __start
|
.globl __start
|
||||||
.globl thread_start
|
|
||||||
.set noreorder
|
.set noreorder
|
||||||
|
|
||||||
#define Status 12
|
|
||||||
#define Config 16
|
|
||||||
|
|
||||||
// Note that this code starts at 0xa0000000, even though it is linked for
|
// Note that this code starts at 0xa0000000, even though it is linked for
|
||||||
// 0x80000000. This means that until the jump below, it must be PIC.
|
// 0x80000000. This means that until the jump below, it must be PIC.
|
||||||
__start:
|
__start:
|
||||||
@ -49,13 +49,14 @@ start_hack_for_disassembler:
|
|||||||
|
|
||||||
// Set kseg0 cachable.
|
// Set kseg0 cachable.
|
||||||
li $k0, 0x3
|
li $k0, 0x3
|
||||||
mtc0 $k0, $Config, 0
|
mtc0 $k0, $CP0_CONFIG, 0
|
||||||
|
|
||||||
// Jump into cached code.
|
// Jump into cached code.
|
||||||
la $t9, 1f
|
la $t9, 1f
|
||||||
jr $t9
|
jr $t9
|
||||||
nop
|
nop
|
||||||
1:
|
1:
|
||||||
|
// From here, the code no longer needs to be PIC.
|
||||||
|
|
||||||
// Clear .bss
|
// Clear .bss
|
||||||
la $a0, _edata
|
la $a0, _edata
|
||||||
@ -64,14 +65,7 @@ start_hack_for_disassembler:
|
|||||||
bne $a1, $a0, 1b
|
bne $a1, $a0, 1b
|
||||||
addu $a0, 4
|
addu $a0, 4
|
||||||
|
|
||||||
// First argument is the memory size: 128 megabytes.
|
// First argument is the memory size.
|
||||||
li $a0, 128 << 20
|
|
||||||
la $t9, init
|
la $t9, init
|
||||||
jr $t9
|
jr $t9
|
||||||
nop
|
li $a0, MEMORY_SIZE
|
||||||
|
|
||||||
thread_start:
|
|
||||||
.word thread0
|
|
||||||
.word thread1
|
|
||||||
.word thread2
|
|
||||||
.word thread3
|
|
||||||
|
15
mips/entry.S
15
mips/entry.S
@ -226,18 +226,3 @@ save_regs:
|
|||||||
la $ra, kernel_exit
|
la $ra, kernel_exit
|
||||||
jr $t9
|
jr $t9
|
||||||
nop
|
nop
|
||||||
|
|
||||||
.globl thread0
|
|
||||||
.globl thread1
|
|
||||||
.globl thread2
|
|
||||||
.globl thread3
|
|
||||||
.balign 0x1000
|
|
||||||
thread0:
|
|
||||||
.incbin "init"
|
|
||||||
.balign 0x1000
|
|
||||||
thread1:
|
|
||||||
.incbin "lcd"
|
|
||||||
.balign 0x1000
|
|
||||||
thread2:
|
|
||||||
.incbin "gpio"
|
|
||||||
thread3:
|
|
||||||
|
@ -260,49 +260,13 @@ void init (unsigned mem):
|
|||||||
// Set up initial threads.
|
// Set up initial threads.
|
||||||
init_threads ()
|
init_threads ()
|
||||||
|
|
||||||
// Disable all gpio interrupts and alternate functions initially.
|
|
||||||
for unsigned i = 0; i < 4; ++i:
|
|
||||||
GPIO_GPIER (i) = 0
|
|
||||||
GPIO_GPALR (i) = 0
|
|
||||||
GPIO_GPAUR (i) = 0
|
|
||||||
// Set up the rest of the hardware (copied from Linux).
|
|
||||||
cpm_idle_mode ()
|
|
||||||
cpm_enable_cko1 ()
|
|
||||||
cpm_start_all ()
|
|
||||||
harb_set_priority (0x08)
|
|
||||||
dmac_enable_all_channels ()
|
|
||||||
harb_usb0_uhc ()
|
|
||||||
gpio_as_emc ()
|
|
||||||
gpio_as_uart0 ()
|
|
||||||
gpio_as_dma ()
|
|
||||||
gpio_as_eth ()
|
|
||||||
gpio_as_usb ()
|
|
||||||
gpio_as_lcd_master ()
|
|
||||||
gpio_as_ssi()
|
|
||||||
gpio_as_msc ()
|
|
||||||
|
|
||||||
gpio_as_gpio (GPIO_CAPS_PORT, GPIO_CAPS)
|
|
||||||
gpio_as_gpio (GPIO_SCROLL_PORT, GPIO_SCROLL)
|
|
||||||
gpio_as_gpio (GPIO_NUM_PORT, GPIO_NUM)
|
|
||||||
gpio_as_gpio (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
|
||||||
gpio_as_gpio (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
|
||||||
|
|
||||||
// Start the operating system timer, and set it to give an interrupt immediately.
|
|
||||||
// This is better, because the kernel starts with jumping into the idle task and
|
|
||||||
// waiting for the first interrupt.
|
|
||||||
unsigned latch = (JZ_EXTAL + (HZ >> 1)) / HZ
|
|
||||||
ost_disable_all ()
|
|
||||||
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
|
|
||||||
ost_set_reload (0, latch)
|
|
||||||
ost_set_count (0, 1)
|
|
||||||
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
|
|
||||||
ost_enable_channel (0)
|
|
||||||
intc_unmask_irq (IRQ_OST0)
|
|
||||||
|
|
||||||
// Unset all interrupt handlers.
|
// Unset all interrupt handlers.
|
||||||
for unsigned i = 0; i < 32; ++i:
|
for unsigned i = 0; i < 32; ++i:
|
||||||
arch_interrupt_receiver[i] = NULL
|
arch_interrupt_receiver[i] = NULL
|
||||||
|
|
||||||
|
// Initialize board-specific things.
|
||||||
|
board_init ()
|
||||||
|
|
||||||
// Say we're handling an exception. Since we're going to enter the idle task, allow access to cp0.
|
// Say we're handling an exception. Since we're going to enter the idle task, allow access to cp0.
|
||||||
// All interrupts enter the CPU through the interrupt controller at IP2, so enable that.
|
// All interrupts enter the CPU through the interrupt controller at IP2, so enable that.
|
||||||
cp0_set (CP0_STATUS, 0x1000ff13)
|
cp0_set (CP0_STATUS, 0x1000ff13)
|
||||||
|
@ -94,7 +94,7 @@ kThread *interrupt ():
|
|||||||
for unsigned i = 0; i < 32; ++i:
|
for unsigned i = 0; i < 32; ++i:
|
||||||
if ipr & (1 << i):
|
if ipr & (1 << i):
|
||||||
// Handle timer interrupts specially: don't disable them.
|
// Handle timer interrupts specially: don't disable them.
|
||||||
if i == IRQ_OST0:
|
if i == TIMER_INTERRUPT:
|
||||||
continue
|
continue
|
||||||
// Disable the interrupt while handling it.
|
// Disable the interrupt while handling it.
|
||||||
intc_mask_irq (i)
|
intc_mask_irq (i)
|
||||||
@ -106,9 +106,15 @@ kThread *interrupt ():
|
|||||||
c.data[j] = 0
|
c.data[j] = 0
|
||||||
arch_interrupt_receiver[i]->send_message (i, &c)
|
arch_interrupt_receiver[i]->send_message (i, &c)
|
||||||
arch_interrupt_receiver[i] = NULL
|
arch_interrupt_receiver[i] = NULL
|
||||||
if ipr & (1 << IRQ_OST0):
|
if ipr & (1 << TIMER_INTERRUPT):
|
||||||
|
#if defined (TRENDTAC)
|
||||||
ost_clear_uf (0)
|
ost_clear_uf (0)
|
||||||
intc_ack_irq (IRQ_OST0)
|
#elif defined (NANONOTE)
|
||||||
|
tcu_clear_full_match_flag (0)
|
||||||
|
#else
|
||||||
|
#error unknown board
|
||||||
|
#endif
|
||||||
|
intc_ack_irq (TIMER_INTERRUPT)
|
||||||
timer_interrupt ()
|
timer_interrupt ()
|
||||||
handle_exit ()
|
handle_exit ()
|
||||||
return current
|
return current
|
||||||
|
66
mips/nanonote/Makefile.arch
Normal file
66
mips/nanonote/Makefile.arch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Iris: micro-kernel for a capability-based operating system.
|
||||||
|
# mips/nanonote/Makefile.arch: nanonote-specific parts of the build rules
|
||||||
|
# Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
load = 0x80000000
|
||||||
|
|
||||||
|
ARCH_CXXFLAGS = -DNUM_THREADS=2
|
||||||
|
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE
|
||||||
|
CROSS = mipsel-linux-gnu-
|
||||||
|
OBJDUMP = $(CROSS)objdump
|
||||||
|
junk = mdebug.abi32 reginfo comment pdr
|
||||||
|
OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
||||||
|
LDFLAGS = --omagic -Ttext $(load)
|
||||||
|
|
||||||
|
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
||||||
|
boot_sources = mips/init.cc mips/nanonote/board.cc
|
||||||
|
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
||||||
|
boot_threads = init udc
|
||||||
|
|
||||||
|
test: iris.raw nanonote-boot
|
||||||
|
./nanonote-boot iris.raw 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris | grep __start$$ | cut -b2-8')
|
||||||
|
.PHONY: test
|
||||||
|
|
||||||
|
%.elf: %.o
|
||||||
|
$(LD) $(LDFLAGS) -o $@ $<
|
||||||
|
|
||||||
|
%.raw: %.elf
|
||||||
|
$(OBJCOPY) -S $(OBJCOPYFLAGS) -Obinary $< $@
|
||||||
|
|
||||||
|
nanonote-boot: mips/nanonote/nanonote-boot.cc mips/nanonote/sdram-setup.raw
|
||||||
|
g++ `pkg-config --cflags --libs shevek` $< -o $@ -D'STAGE1="$<"' -lusb
|
||||||
|
|
||||||
|
mips/nanonote/sdram-setup.elf: mips/nanonote/sdram-setup.ld
|
||||||
|
mips/nanonote/sdram-setup.elf: LDFLAGS = --omagic -T mips/nanonote/sdram-setup.ld
|
||||||
|
mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20"
|
||||||
|
mips/entry.o: $(boot_threads)
|
||||||
|
mips/init.o: TARGET_FLAGS = -I/usr/include
|
||||||
|
$(boot_threads): TARGET_FLAGS = -I.
|
||||||
|
$(boot_threads): LDFLAGS = -EL
|
||||||
|
$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh boot-programs/init.hh
|
||||||
|
lcd: boot-programs/charset.data
|
||||||
|
|
||||||
|
boot-programs/charset.data: boot-programs/charset
|
||||||
|
$< > $@
|
||||||
|
|
||||||
|
%.o:%.S Makefile Makefile.arch mips/arch.hh
|
||||||
|
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@
|
||||||
|
|
||||||
|
# entry.o must be the first file. threadlist.o must be the first of the init objects (which can be freed after loading).
|
||||||
|
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
|
||||||
|
$(LD) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
|
ARCH_CLEAN_FILES = $(boot_sources) $(boot_threads) $(arch_headers) boot_programs/init.hh boot_programs/devices.hh mips/*.o mips/nanonote/*.o boot-programs/charset.data iris.elf iris.raw mips/nanonote/sdram-setup.elf mips/nanonote/sdram-setup.raw
|
51
mips/nanonote/board.ccp
Normal file
51
mips/nanonote/board.ccp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pypp 0
|
||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/nanonote/board.ccp: nanonote-specific definitions.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#define ARCH
|
||||||
|
#define INIT
|
||||||
|
#include "kernel.hh"
|
||||||
|
|
||||||
|
void board_init ():
|
||||||
|
cpm_start_all ()
|
||||||
|
gpio_as_uart0 ()
|
||||||
|
gpio_as_sdram_16bit ()
|
||||||
|
gpio_as_nand ()
|
||||||
|
gpio_as_aic ()
|
||||||
|
gpio_as_lcd_16bit ()
|
||||||
|
gpio_as_msc ()
|
||||||
|
// Set up keyboard: this breaks uart receive.
|
||||||
|
gpio_as_gpio (3, 0x05fc0000)
|
||||||
|
tcu_stop_counter (0)
|
||||||
|
tcu_select_extalclk (0)
|
||||||
|
tcu_select_clk_div1 (0)
|
||||||
|
tcu_disable_pwm_output (0)
|
||||||
|
tcu_set_full_data (0, JZ_EXTAL / HZ)
|
||||||
|
tcu_mask_half_match_irq (0)
|
||||||
|
tcu_clear_full_match_flag (0)
|
||||||
|
tcu_unmask_full_match_irq (0)
|
||||||
|
tcu_start_counter (0)
|
||||||
|
// Set up uart.
|
||||||
|
uart_disable (0)
|
||||||
|
uart_set_baud (0, JZ_EXTAL, 9600)
|
||||||
|
uart_set_8n1 (0)
|
||||||
|
UART0_IER = 0
|
||||||
|
UART0_MCR = 0
|
||||||
|
UART0_SIRCR = 0
|
||||||
|
UART0_UMR = 0
|
||||||
|
UART0_UACR = 0
|
||||||
|
UART0_FCR |= UARTFCR_UUE | UARTFCR_RFLS | UARTFCR_TFLS
|
19
mips/nanonote/board.hhp
Normal file
19
mips/nanonote/board.hhp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pypp 0
|
||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/nanonote/board.hhp: nanonote-specific declarations and type definitions.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "jz4740.hh"
|
3568
mips/nanonote/jz4740.hhp
Normal file
3568
mips/nanonote/jz4740.hhp
Normal file
File diff suppressed because it is too large
Load Diff
188
mips/nanonote/nanonote-boot.ccp
Normal file
188
mips/nanonote/nanonote-boot.ccp
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
#pypp 0
|
||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/nanonote/nanonote-boot.ccp: Host-side helper for booting over USB.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <usb.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
asm volatile (".section .rodata\n"
|
||||||
|
".globl stage1\n"
|
||||||
|
".globl stage1_end\n"
|
||||||
|
"stage1:\n"
|
||||||
|
".incbin \"mips/nanonote/sdram-setup.raw\"\n"
|
||||||
|
"stage1_end:\n"
|
||||||
|
".section .text")
|
||||||
|
extern char stage1[1]
|
||||||
|
extern char stage1_end[1]
|
||||||
|
|
||||||
|
unsigned const stage1_load = 0x80002000
|
||||||
|
unsigned const stage1_start = 0x80002000
|
||||||
|
unsigned const stage1_size = stage1_end - stage1
|
||||||
|
|
||||||
|
class nanonote:
|
||||||
|
public:
|
||||||
|
|
||||||
|
nanonote (unsigned skip = 0)
|
||||||
|
void boot (std::string const &data, unsigned load, unsigned start)
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum requests:
|
||||||
|
VR_GET_CPU_INFO = 0
|
||||||
|
VR_SET_DATA_ADDRESS = 1
|
||||||
|
VR_SET_DATA_LENGTH = 2
|
||||||
|
VR_FLUSH_CACHES = 3
|
||||||
|
VR_PROGRAM_START1 = 4
|
||||||
|
VR_PROGRAM_START2 = 5
|
||||||
|
static int const vendor = 0x601a
|
||||||
|
static int const product = 0x4740
|
||||||
|
static unsigned const timeout = 1000
|
||||||
|
usb_dev_handle *handle
|
||||||
|
int interface
|
||||||
|
int in_ep, out_ep
|
||||||
|
std::string cpu_info
|
||||||
|
bool try_open (struct usb_device *dev)
|
||||||
|
bool find_device (unsigned skip)
|
||||||
|
void request (requests num, unsigned data = 0)
|
||||||
|
void send_file (unsigned address, unsigned size, char const *data)
|
||||||
|
void get_cpu_info ()
|
||||||
|
|
||||||
|
bool nanonote::try_open (struct usb_device *dev):
|
||||||
|
handle = usb_open (dev)
|
||||||
|
|
||||||
|
if dev->descriptor.bNumConfigurations != 1:
|
||||||
|
usb_close (handle)
|
||||||
|
std::cerr << dev->descriptor.bNumConfigurations << " configurations\n"
|
||||||
|
return false
|
||||||
|
if usb_set_configuration (handle, 1) < 0:
|
||||||
|
usb_close (handle)
|
||||||
|
std::cerr << "Can't set configuration 1: " << usb_strerror () << '\n'
|
||||||
|
return false
|
||||||
|
|
||||||
|
interface = dev->config->interface->altsetting->bInterfaceNumber
|
||||||
|
int have_in = 0, have_out = 0
|
||||||
|
for unsigned i = 0; i < dev->config->interface->altsetting->bNumEndpoints; ++i:
|
||||||
|
if (dev->config->interface->altsetting->endpoint[i].bmAttributes & USB_ENDPOINT_TYPE_MASK) != USB_ENDPOINT_TYPE_BULK:
|
||||||
|
usb_close (handle)
|
||||||
|
std::cerr << "Device has non-bulk endpoint.\n"
|
||||||
|
return false
|
||||||
|
if (dev->config->interface->altsetting->endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK):
|
||||||
|
/* input */
|
||||||
|
if have_in:
|
||||||
|
usb_close (handle)
|
||||||
|
std::cerr << "Device has multiple IN endpoints.\n"
|
||||||
|
return false
|
||||||
|
have_in = 1
|
||||||
|
in_ep = dev->config->interface->altsetting->endpoint[i].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK
|
||||||
|
if in_ep != 1:
|
||||||
|
usb_close (handle)
|
||||||
|
std::cerr << "IN endpoint is not numbered as 1.\n"
|
||||||
|
return false
|
||||||
|
else:
|
||||||
|
/* output */
|
||||||
|
if have_out:
|
||||||
|
usb_close (handle)
|
||||||
|
std::cerr << "Device has multiple OUT endpoints.\n"
|
||||||
|
return false
|
||||||
|
have_out = 1
|
||||||
|
out_ep = dev->config->interface->altsetting->endpoint[i].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK
|
||||||
|
if out_ep != 1:
|
||||||
|
usb_close (handle)
|
||||||
|
std::cerr << "OUT endpoint is not numbered as 1.\n"
|
||||||
|
return false
|
||||||
|
if usb_claim_interface (handle, interface) < 0:
|
||||||
|
std::cerr << "unable to claim interface\n"
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
bool nanonote::find_device (unsigned skip):
|
||||||
|
unsigned skipped = 0
|
||||||
|
usb_init ()
|
||||||
|
usb_find_busses ()
|
||||||
|
usb_find_devices ()
|
||||||
|
for struct usb_bus *bus = usb_busses; bus; bus = bus->next:
|
||||||
|
for struct usb_device *dev = bus->devices; dev; dev = dev->next:
|
||||||
|
if dev->descriptor.idProduct != product || dev->descriptor.idVendor != vendor:
|
||||||
|
continue
|
||||||
|
if skip > skipped++:
|
||||||
|
continue
|
||||||
|
if try_open (dev):
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
nanonote::nanonote (unsigned skip):
|
||||||
|
if !find_device (skip):
|
||||||
|
std::cerr << "unable to find NanoNote device.\n";
|
||||||
|
throw "unable to find NanoNote device";
|
||||||
|
|
||||||
|
void nanonote::get_cpu_info ():
|
||||||
|
char buffer[8]
|
||||||
|
if usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VR_GET_CPU_INFO, 0, 0, buffer, 8, timeout) < 0:
|
||||||
|
std::cerr << "unable to request cpu info from NanoNote: " << usb_strerror () << ".\n"
|
||||||
|
throw "unable to request cpu info from NanoNote"
|
||||||
|
cpu_info = std::string (buffer, 8)
|
||||||
|
|
||||||
|
void nanonote::request (requests r, unsigned data):
|
||||||
|
std::cerr << "requesting " << r << " (data = " << std::hex << data << ")" << std::endl
|
||||||
|
if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, r, (data >> 16) & 0xffff, data & 0xffff, NULL, 0, timeout) < 0:
|
||||||
|
std::cerr << "unable to send control message to NanoNote: " << usb_strerror () << ".\n"
|
||||||
|
throw "unable to send control message to NanoNote"
|
||||||
|
|
||||||
|
void nanonote::send_file (unsigned address, unsigned size, char const *data):
|
||||||
|
request (VR_SET_DATA_ADDRESS, address)
|
||||||
|
//request (VR_SET_DATA_LENGTH, size)
|
||||||
|
char const *ptr = data
|
||||||
|
while ptr - data < size:
|
||||||
|
int ret = usb_bulk_write (handle, out_ep, ptr, size - (ptr - data), timeout)
|
||||||
|
if ret <= 0:
|
||||||
|
std::cerr << "failed to write to NanoNote.\n"
|
||||||
|
throw "failed to write to NanoNote"
|
||||||
|
ptr += ret
|
||||||
|
|
||||||
|
void nanonote::boot (std::string const &data, unsigned load, unsigned start):
|
||||||
|
get_cpu_info ()
|
||||||
|
std::cerr << "info: " << cpu_info << std::endl
|
||||||
|
send_file (stage1_load, stage1_size, stage1)
|
||||||
|
request (VR_PROGRAM_START1, stage1_start)
|
||||||
|
usleep (100)
|
||||||
|
send_file (load, data.size (), data.data ())
|
||||||
|
request (VR_FLUSH_CACHES)
|
||||||
|
request (VR_PROGRAM_START2, start)
|
||||||
|
get_cpu_info ()
|
||||||
|
std::cerr << "info: " << cpu_info << std::endl
|
||||||
|
|
||||||
|
int main (int argc, char **argv):
|
||||||
|
if argc != 3:
|
||||||
|
std::cerr << "Usage: " << argv[0] << " [kernel] [entry address]\n"
|
||||||
|
std::cerr << "The kernel is loaded from 0x80000000 and run from entry address\n"
|
||||||
|
return 1
|
||||||
|
unsigned entry = strtoul (argv[2], NULL, 0)
|
||||||
|
nanonote nn
|
||||||
|
std::ifstream file (argv[1])
|
||||||
|
if !file:
|
||||||
|
std::cerr << "can't open file '" << argv[1] << "' for reading.\n"
|
||||||
|
return 1
|
||||||
|
std::ostringstream data
|
||||||
|
data << file.rdbuf ()
|
||||||
|
if data.str ().empty ():
|
||||||
|
std::cerr << "no data read from '" << argv[1] << "'.\n"
|
||||||
|
return 1
|
||||||
|
nn.boot (data.str (), 0x80000000, entry)
|
||||||
|
return 0
|
136
mips/nanonote/sdram-setup.ccp
Normal file
136
mips/nanonote/sdram-setup.ccp
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
#pypp 0
|
||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/nanonote/sdram-setup.ccp: bootstrapping over usb.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// This runs like the kernel. In particular, it doesn't want userspace declarations.
|
||||||
|
#define __KERNEL
|
||||||
|
#include "jz4740.hh"
|
||||||
|
|
||||||
|
#define CONFIG_NR_DRAM_BANKS 1 // SDRAM BANK Number: 1, 2
|
||||||
|
#define SDRAM_CASL 3 // CAS latency: 2 or 3
|
||||||
|
// SDRAM Timings, unit: ns
|
||||||
|
#define SDRAM_TRAS 45 // RAS# Active Time
|
||||||
|
#define SDRAM_RCD 20 // RAS# to CAS# Delay
|
||||||
|
#define SDRAM_TPC 20 // RAS# Precharge Time
|
||||||
|
#define SDRAM_TRWL 7 // Write Latency Time
|
||||||
|
#define SDRAM_TREF 15625 // Refresh period: 4096 refresh cycles/64ms
|
||||||
|
|
||||||
|
asm volatile (".set noreorder\n"
|
||||||
|
"\t.globl __start\n"
|
||||||
|
"\t.text\n"
|
||||||
|
"__start:\n"
|
||||||
|
"\tla $sp, 0x80004000\n"
|
||||||
|
"__hack_label:\n"
|
||||||
|
"\tmove $a0, $ra\n"
|
||||||
|
"\tbal 1f\n"
|
||||||
|
"\tnop\n"
|
||||||
|
"\t.word _gp\n"
|
||||||
|
"1:\n"
|
||||||
|
"\tlw $gp, 0($ra)\n"
|
||||||
|
"\tla $t9, start_cpp\n"
|
||||||
|
"\tmove $ra, $a0\n"
|
||||||
|
"\tjr $t9\n"
|
||||||
|
"\tnop\n"
|
||||||
|
".set reorder")
|
||||||
|
|
||||||
|
extern "C":
|
||||||
|
void start_cpp ()
|
||||||
|
|
||||||
|
void start_cpp ():
|
||||||
|
unsigned dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns
|
||||||
|
unsigned cas_latency_sdmr[2] = { EMC_SDMR_CAS_2, EMC_SDMR_CAS_3 }
|
||||||
|
unsigned cas_latency_dmcr[2] = { 1 << EMC_DMCR_TCL_BIT, 2 << EMC_DMCR_TCL_BIT }
|
||||||
|
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32}
|
||||||
|
|
||||||
|
cpu_clk = 225000000
|
||||||
|
gpio_as_sdram_32bit ()
|
||||||
|
unsigned SDRAM_BW16 = 0
|
||||||
|
unsigned SDRAM_BANK4 = 1
|
||||||
|
unsigned SDRAM_ROW = 13
|
||||||
|
unsigned SDRAM_COL = 9
|
||||||
|
|
||||||
|
mem_clk = cpu_clk * div[cpm_get_cdiv()] / div[cpm_get_mdiv()]
|
||||||
|
EMC_BCR = 0
|
||||||
|
EMC_RTCSR = 0
|
||||||
|
#define SDRAM_ROW0 11
|
||||||
|
#define SDRAM_COL0 8
|
||||||
|
#define SDRAM_BANK40 0
|
||||||
|
dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) | ((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) | (SDRAM_BANK40<<EMC_DMCR_BA_BIT) | (SDRAM_BW16<<EMC_DMCR_BW_BIT) | EMC_DMCR_EPIN | cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]
|
||||||
|
// Basic DMCR value
|
||||||
|
dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) | ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) | (SDRAM_BANK4<<EMC_DMCR_BA_BIT) | (SDRAM_BW16<<EMC_DMCR_BW_BIT) | EMC_DMCR_EPIN | cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)]
|
||||||
|
// SDRAM timimg
|
||||||
|
ns = 1000000000 / mem_clk
|
||||||
|
tmp = SDRAM_TRAS / ns
|
||||||
|
if tmp < 4:
|
||||||
|
tmp = 4
|
||||||
|
if tmp > 11:
|
||||||
|
tmp = 11
|
||||||
|
dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT)
|
||||||
|
tmp = SDRAM_RCD/ns
|
||||||
|
if tmp > 3:
|
||||||
|
tmp = 3
|
||||||
|
dmcr |= (tmp << EMC_DMCR_RCD_BIT)
|
||||||
|
tmp = SDRAM_TPC/ns
|
||||||
|
if tmp > 7:
|
||||||
|
tmp = 7
|
||||||
|
dmcr |= (tmp << EMC_DMCR_TPC_BIT)
|
||||||
|
tmp = SDRAM_TRWL/ns
|
||||||
|
if tmp > 3:
|
||||||
|
tmp = 3
|
||||||
|
dmcr |= (tmp << EMC_DMCR_TRWL_BIT)
|
||||||
|
tmp = (SDRAM_TRAS + SDRAM_TPC)/ns
|
||||||
|
if tmp > 14:
|
||||||
|
tmp = 14
|
||||||
|
dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT)
|
||||||
|
|
||||||
|
// SDRAM mode value
|
||||||
|
sdmode = EMC_SDMR_BT_SEQ | EMC_SDMR_OM_NORMAL | EMC_SDMR_BL_4 | cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
|
||||||
|
|
||||||
|
// Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0
|
||||||
|
EMC_DMCR = dmcr
|
||||||
|
REG8(EMC_SDMR0|sdmode) = 0
|
||||||
|
|
||||||
|
// Wait for precharge, > 200us
|
||||||
|
tmp = (cpu_clk / 1000000) * 1000
|
||||||
|
volatile unsigned t = tmp
|
||||||
|
while t--:
|
||||||
|
|
||||||
|
// Stage 2. Enable auto-refresh
|
||||||
|
EMC_DMCR = dmcr | EMC_DMCR_RFSH
|
||||||
|
|
||||||
|
tmp = SDRAM_TREF/ns
|
||||||
|
tmp = tmp/64 + 1
|
||||||
|
if tmp > 0xff:
|
||||||
|
tmp = 0xff
|
||||||
|
EMC_RTCOR = tmp
|
||||||
|
EMC_RTCNT = 0
|
||||||
|
// Divisor is 64, CKO/64
|
||||||
|
EMC_RTCSR = EMC_RTCSR_CKS_64
|
||||||
|
|
||||||
|
// Wait for number of auto-refresh cycles
|
||||||
|
tmp = (cpu_clk / 1000000) * 1000
|
||||||
|
t = tmp
|
||||||
|
while t--:
|
||||||
|
|
||||||
|
// Stage 3. Mode Register Set
|
||||||
|
EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET
|
||||||
|
REG8(EMC_SDMR0|sdmode) = 0
|
||||||
|
|
||||||
|
// Set back to basic DMCR value
|
||||||
|
EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET
|
||||||
|
|
||||||
|
// everything is ok now: return to boot loader to load stage 2.
|
31
mips/nanonote/sdram-setup.ld
Normal file
31
mips/nanonote/sdram-setup.ld
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
OUTPUT_ARCH(mips)
|
||||||
|
ENTRY(__start)
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram : ORIGIN = 0x80002000 , LENGTH = 0x100000
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
.text : { *(.text*) } > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.rodata : { *(.rodata*) } > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.sdata : { *(.sdata*) } > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.data : { *(.data*) *(.scommon*) *(.reginfo*) } > ram
|
||||||
|
|
||||||
|
_gp = ABSOLUTE(.); /* Base of small data */
|
||||||
|
|
||||||
|
.got : { *(.got*) } > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.sbss : { *(.sbss*) } > ram
|
||||||
|
.bss : { *(.bss*) } > ram
|
||||||
|
. = ALIGN (4);
|
||||||
|
}
|
||||||
|
|
38
mips/nanonote/threadlist.S
Normal file
38
mips/nanonote/threadlist.S
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/nanonote/threadlist.S: List of initial threads.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
.globl init_start
|
||||||
|
.globl thread_start
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
|
thread0:
|
||||||
|
.incbin "init"
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
|
thread1:
|
||||||
|
.incbin "udc"
|
||||||
|
|
||||||
|
thread2:
|
||||||
|
|
||||||
|
// Everything from here may be freed after kernel initialization.
|
||||||
|
init_start:
|
||||||
|
|
||||||
|
thread_start:
|
||||||
|
.word thread0
|
||||||
|
.word thread1
|
||||||
|
.word thread2
|
61
mips/trendtac/Makefile.arch
Normal file
61
mips/trendtac/Makefile.arch
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# Iris: micro-kernel for a capability-based operating system.
|
||||||
|
# mips/trendtac/Makefile.arch: board-specific parts of the build rules
|
||||||
|
# Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
load = 0x80000000
|
||||||
|
|
||||||
|
ARCH_CXXFLAGS = -DNUM_THREADS=3
|
||||||
|
ARCH_CPPFLAGS = -Imips -Wa,-mips32
|
||||||
|
CROSS = mipsel-linux-gnu-
|
||||||
|
OBJDUMP = $(CROSS)objdump
|
||||||
|
junk = mdebug.abi32 reginfo comment pdr
|
||||||
|
OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
||||||
|
|
||||||
|
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
||||||
|
boot_sources = mips/init.cc
|
||||||
|
arch_headers = mips/arch.hh mips/jz4730.hh
|
||||||
|
boot_threads = init gpio lcd
|
||||||
|
|
||||||
|
uimage:
|
||||||
|
|
||||||
|
mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE = "128 << 20"
|
||||||
|
mips/threadlist.o: $(boot_threads)
|
||||||
|
mips/init.o: TARGET_FLAGS = -I/usr/include
|
||||||
|
$(boot_threads): TARGET_FLAGS = -I.
|
||||||
|
$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh boot-programs/init.hh
|
||||||
|
lcd: boot-programs/charset.data
|
||||||
|
|
||||||
|
boot-programs/charset.data: boot-programs/charset
|
||||||
|
$< > $@
|
||||||
|
|
||||||
|
# Transform ':' into ';' so vim doesn't think there are errors.
|
||||||
|
uimage: iris.raw.gz Makefile mips/Makefile.arch
|
||||||
|
mkimage -A MIPS -O Linux -C gzip -a $(load) -e 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris | grep __start$$ | cut -b2-8') -n "Iris" -d $< $@ | sed -e 's/:/;/g'
|
||||||
|
|
||||||
|
%.o:%.S Makefile Makefile.arch mips/arch.hh
|
||||||
|
$(CC) $(CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@
|
||||||
|
|
||||||
|
# entry.o must be the first file. threadlist.o must be the first of the init objects (which can be freed after loading).
|
||||||
|
iris: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/trendtac/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
|
||||||
|
$(LD) --omagic -Ttext $(load) $^ -o $@
|
||||||
|
|
||||||
|
%.raw: %
|
||||||
|
$(OBJCOPY) -S $(OBJCOPYFLAGS) -Obinary $< $@
|
||||||
|
|
||||||
|
%.gz: %
|
||||||
|
gzip < $< > $@
|
||||||
|
|
||||||
|
ARCH_CLEAN_FILES = uimage $(boot_threads) mips/*.o boot-programs/charset.data iris iris.raw iris.raw.gz
|
57
mips/trendtac/board.ccp
Normal file
57
mips/trendtac/board.ccp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#pypp 0
|
||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/trendtac/board.ccp: trendtac-specific functions.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
void board_init ():
|
||||||
|
// Disable all gpio interrupts and alternate functions initially.
|
||||||
|
for unsigned i = 0; i < 4; ++i:
|
||||||
|
GPIO_GPIER (i) = 0
|
||||||
|
GPIO_GPALR (i) = 0
|
||||||
|
GPIO_GPAUR (i) = 0
|
||||||
|
// Set up the rest of the hardware (copied from Linux).
|
||||||
|
cpm_idle_mode ()
|
||||||
|
cpm_enable_cko1 ()
|
||||||
|
cpm_start_all ()
|
||||||
|
harb_set_priority (0x08)
|
||||||
|
dmac_enable_all_channels ()
|
||||||
|
harb_usb0_uhc ()
|
||||||
|
gpio_as_emc ()
|
||||||
|
gpio_as_uart0 ()
|
||||||
|
gpio_as_dma ()
|
||||||
|
gpio_as_eth ()
|
||||||
|
gpio_as_usb ()
|
||||||
|
gpio_as_lcd_master ()
|
||||||
|
gpio_as_ssi()
|
||||||
|
gpio_as_msc ()
|
||||||
|
|
||||||
|
gpio_as_gpio (GPIO_CAPS_PORT, GPIO_CAPS)
|
||||||
|
gpio_as_gpio (GPIO_SCROLL_PORT, GPIO_SCROLL)
|
||||||
|
gpio_as_gpio (GPIO_NUM_PORT, GPIO_NUM)
|
||||||
|
gpio_as_gpio (GPIO_TP_LEFT_PORT, GPIO_TP_LEFT)
|
||||||
|
gpio_as_gpio (GPIO_TP_RIGHT_PORT, GPIO_TP_RIGHT)
|
||||||
|
|
||||||
|
// Start the operating system timer, and set it to give an interrupt immediately.
|
||||||
|
// This is better, because the kernel starts with jumping into the idle task and
|
||||||
|
// waiting for the first interrupt.
|
||||||
|
unsigned latch = (JZ_EXTAL + (HZ >> 1)) / HZ
|
||||||
|
ost_disable_all ()
|
||||||
|
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
|
||||||
|
ost_set_reload (0, latch)
|
||||||
|
ost_set_count (0, 1)
|
||||||
|
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
|
||||||
|
ost_enable_channel (0)
|
||||||
|
intc_unmask_irq (IRQ_OST0)
|
@ -25,6 +25,8 @@
|
|||||||
#define JZ_EXTAL 3686400
|
#define JZ_EXTAL 3686400
|
||||||
// RTC clock
|
// RTC clock
|
||||||
#define RTC_CLOCK 32768
|
#define RTC_CLOCK 32768
|
||||||
|
// The interrupt source that is used for the system timer
|
||||||
|
#define TIMER_INTERRUPT IRQ_OST0
|
||||||
|
|
||||||
// Physical addresses are where they really are.
|
// Physical addresses are where they really are.
|
||||||
#define HARB_PHYSICAL 0x13000000
|
#define HARB_PHYSICAL 0x13000000
|
43
mips/trendtac/threadlist.S
Normal file
43
mips/trendtac/threadlist.S
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Iris: micro-kernel for a capability-based operating system.
|
||||||
|
// mips/trendtac/threadlist.S: Kernel entry point, called by the boot loader.
|
||||||
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||||
|
//
|
||||||
|
// 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
.globl init_start
|
||||||
|
.globl thread_start
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
|
thread0:
|
||||||
|
.incbin "init"
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
|
thread1:
|
||||||
|
.incbin "lcd"
|
||||||
|
|
||||||
|
.balign 0x1000
|
||||||
|
thread2:
|
||||||
|
.incbin "gpio"
|
||||||
|
|
||||||
|
thread3:
|
||||||
|
|
||||||
|
// Everything from here may be freed after kernel initialization.
|
||||||
|
init_start:
|
||||||
|
|
||||||
|
thread_start:
|
||||||
|
.word thread0
|
||||||
|
.word thread1
|
||||||
|
.word thread2
|
||||||
|
.word thread3
|
@ -19,6 +19,11 @@
|
|||||||
#define ARCH
|
#define ARCH
|
||||||
#include "kernel.hh"
|
#include "kernel.hh"
|
||||||
|
|
||||||
|
#ifdef USE_SERIAL
|
||||||
|
void dbg_log_char (unsigned ch):
|
||||||
|
while !(UART0_LSR & UARTLSR_TDRQ):
|
||||||
|
UART0_TDR = ch
|
||||||
|
#else
|
||||||
void dbg_log_char (unsigned ch):
|
void dbg_log_char (unsigned ch):
|
||||||
if !dbg_cap.valid ():
|
if !dbg_cap.valid ():
|
||||||
return
|
return
|
||||||
@ -27,6 +32,7 @@ void dbg_log_char (unsigned ch):
|
|||||||
++dbg_code.l
|
++dbg_code.l
|
||||||
dbg_cap->invoke (&c)
|
dbg_cap->invoke (&c)
|
||||||
--dbg_code.l
|
--dbg_code.l
|
||||||
|
#endif
|
||||||
|
|
||||||
void dbg_log (char const *str):
|
void dbg_log (char const *str):
|
||||||
while *str:
|
while *str:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user