1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-07-02 21:34:32 +03:00

working on lcd

This commit is contained in:
Bas Wijnen 2009-06-10 21:42:01 +02:00
parent 9a7abe2fd5
commit 1bb67efc75
9 changed files with 4470 additions and 266 deletions

View File

@ -183,131 +183,168 @@ do { \
// Pins on the trendtac: // Pins on the trendtac:
0 keyboard 0.00 keyboard
1 keyboard 0.01 keyboard
2 keyboard 0.02 keyboard
3 keyboard 0.03 keyboard
4 keyboard 0.04 keyboard
5 keyboard 0.05 keyboard
6 keyboard 0.06 keyboard
7 keyboard 0.07 keyboard
8 keyboard interrupt 0.08 keyboard interrupt?
9 0.09
10 0.10
11 0.11
12 0.12
13 touchpad right button 0.13 touchpad right button
14 0.14
15 0.15
16 touchpad left button 0.16 touchpad left button
17 0.17
18 0.18
19 0.19
20 0.20
21 0.21
22 0.22
23 0.23
24 0.24
25 0.25
26 0.26
27 0.27
28 0.28
29 0.29
30 0.30
31 0.31
32 1.00
33 1.01
34 1.02
35 1.03
36 1.04
37 1.05
38 1.06
39 1.07
40 1.08
41 1.09
42 1.10
43 1.11
44 1.12
45 1.13
46 1.14
47 1.15
48 1.16
49 1.17
50 1.18
51 1.19
52 1.20
53 1.21
54 1.22
55 1.23
56 1.24
57 1.25
58 1.26
59 1.27
60 1.28
61 1.29
62 1.30
63 1.31
64 2.00 SPEN: lcd enable
65 2.01 SPCK: lcd clock
66 2.02 SPDA: lcd data
67 2.03 LCD_RET: lcd reset
68 2.04
69 2.05
70 2.06
71 2.07
72 2.08
73 2.09
74 2.10
75 2.11
76 2.12
77 2.13
78 2.14
79 2.15
80 2.16
81 2.17
82 2.18
83 2.19
84 2.20
85 2.21
86 2.22
87 2.23
88 2.24
89 2.25
90 2.26
91 2.27
92 2.28
93 2.29
94 2.30 PWM enable (for lcd backlight)
95 2.31
96 keyboard 3.00 keyboard
97 keyboard 3.01 keyboard
98 keyboard 3.02 keyboard
99 keyboard 3.03 keyboard
100 keyboard 3.04 keyboard
101 keyboard 3.05 keyboard
102 keyboard 3.06 keyboard
103 keyboard 3.07 keyboard
104 keyboard 3.08 keyboard
105 keyboard 3.09 keyboard
106 keyboard 3.10 keyboard
107 keyboard 3.11 keyboard
108 keyboard 3.12 keyboard
109 keyboard 3.13 keyboard
110 keyboard 3.14 keyboard
111 keyboard 3.15 keyboard
112 3.16
113 3.17
114 3.18
115 3.19
116 3.20
117 3.21
118 3.22
119 3.23
120 3.24
121 3.25
122 3.26
123 3.27
124 3.28
125 keyboard 3.29 keyboard
126 3.30
127 3.31
Devices enabled in linux:
+ __harb_usb0_uhc();
+ __gpio_as_emc();
+ __gpio_as_uart0();
+ __gpio_as_dma();
+ __gpio_as_eth();
+ __gpio_as_usb();
+ __gpio_as_lcd_master();
+#if defined(CONFIG_I2S_AK4642EN)
+//wjx __gpio_as_scc1();
+ __gpio_as_i2s_master(); //wjx
+#endif
+#if defined(CONFIG_I2S_TSC2301) || defined(CONFIG_I2S_TLC320AIC23)
+ __gpio_as_ssi();
+#endif
+ //__gpio_as_ac97();
+#if defined(CONFIG_I2S_TSC2301) || defined(CONFIG_I2S_TLC320AIC23) || defined(CONFIG_I2S_CS42L51)
+ __gpio_as_i2s_slave();
+#endif
+//wjx __gpio_as_cim();
+ __gpio_as_msc();
+
+/* wjx
+ __gpio_as_output(GPIO_LED_EN);
+ __gpio_set_pin(GPIO_LED_EN);
+
+ __gpio_as_output(GPIO_DISP_OFF_N);
+ __gpio_set_pin(GPIO_DISP_OFF_N);
+*/
+ __gpio_as_output(GPIO_PWM0);
+ __gpio_set_pin(GPIO_PWM0);
+
+
+//wjx __gpio_as_input(GPIO_RTC_IRQ);
+ __gpio_as_output(GPIO_USB_CLK_EN);
+ __gpio_set_pin(GPIO_USB_CLK_EN);

3901
boot-programs/jz4730.hhp Normal file

File diff suppressed because it is too large Load Diff

326
boot-programs/lcd.ccp Normal file
View File

@ -0,0 +1,326 @@
#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// lcd.ccp: Display 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 "iris.h"
// gpio stuff
#define D(n) (*(volatile unsigned *)(0x00 + 0x30 * n + gpio_address))
#define DI(n) (*(volatile unsigned *)(0x04 + 0x30 * n + gpio_address))
#define PU(n) (*(volatile unsigned *)(0x0c + 0x30 * n + gpio_address))
#define AL(n) (*(volatile unsigned *)(0x10 + 0x30 * n + gpio_address))
#define AU(n) (*(volatile unsigned *)(0x14 + 0x30 * n + gpio_address))
#define IE(n) (*(volatile unsigned *)(0x20 + 0x30 * n + gpio_address))
// pwm stuff
#define CTR (*(volatile unsigned char *)(pwm_address + 0x00))
#define PER (*(volatile unsigned short *)(pwm_address + 0x04))
#define DUT (*(volatile unsigned short *)(pwm_address + 0x08))
#define CPM_MSCR (*(volatile unsigned *)(cpm_address + 0x20))
// Mapping address for I/O memory.
unsigned const gpio_address = 0x00001000
unsigned const pwm_address = 0x00002000
unsigned const lcd_address = 0x00003000
unsigned const cpm_address = 0x00004000
//#define PWM0_BASE 0xB0050000
//#define PWM1_BASE 0xB0051000
/* PWM Control Register (PWM_CTR) */
//#define PWM_CTR_EN (1 << 7)
//#define PWM_CTR_SD (1 << 6)
//#define PWM_CTR_PRESCALE_MASK 0x3f
/* PWM Period Register (PWM_PER) */
//#define PWM_PER_PERIOD_MASK 0x3ff
/* PWM Duty Register (PWM_DUT) */
//#define PWM_DUT_FDUTY (1 << 10)
//#define PWM_DUT_DUTY_MASK 0x3ff
// Pin definitions, all in port 2.
#define PWM_ENABLE (1 << 30)
#define SPEN (1 << 0) //LCD_SPL
#define SPCK (1 << 1) //LCD_CLS
#define SPDA (1 << 2) //LCD_PS
#define LCD_RET (1 << 3) //LCD_REV //use for lcd reset
// Lcd register definitions.
#define LCD_CFG (*(volatile unsigned *)(lcd_address + 0x00))
#define LCD_VSYNC (*(volatile unsigned *)(lcd_address + 0x04))
#define LCD_HSYNC (*(volatile unsigned *)(lcd_address + 0x08))
#define LCD_VAT (*(volatile unsigned *)(lcd_address + 0x0c))
#define LCD_DAH (*(volatile unsigned *)(lcd_address + 0x10))
#define LCD_DAV (*(volatile unsigned *)(lcd_address + 0x14))
#define LCD_PS (*(volatile unsigned *)(lcd_address + 0x18))
#define LCD_CLS (*(volatile unsigned *)(lcd_address + 0x1c))
#define LCD_SPL (*(volatile unsigned *)(lcd_address + 0x20))
#define LCD_REV (*(volatile unsigned *)(lcd_address + 0x24))
#define LCD_CTRL (*(volatile unsigned *)(lcd_address + 0x30))
#define LCD_STATE (*(volatile unsigned *)(lcd_address + 0x34))
#define LCD_IID (*(volatile unsigned *)(lcd_address + 0x38))
#define LCD_DA0 (*(volatile unsigned *)(lcd_address + 0x40))
#define LCD_SA0 (*(volatile unsigned *)(lcd_address + 0x44))
#define LCD_FID0 (*(volatile unsigned *)(lcd_address + 0x48))
#define LCD_CMD0 (*(volatile unsigned *)(lcd_address + 0x4c))
#define LCD_DA1 (*(volatile unsigned *)(lcd_address + 0x50))
#define LCD_SA1 (*(volatile unsigned *)(lcd_address + 0x54))
#define LCD_FID1 (*(volatile unsigned *)(lcd_address + 0x58))
#define LCD_CMD1 (*(volatile unsigned *)(lcd_address + 0x5c))
// Bit definitions.
#define LCD_CFG_PDW_BIT 4
#define LCD_CFG_PDW_MASK (0x03 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_1 (0 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_2 (1 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_4 (2 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_8 (3 << LCD_DEV_PDW_BIT)
#define LCD_CFG_MODE_BIT 0
#define LCD_CFG_MODE_MASK (0x0f << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_GENERIC_TFT (0 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SHARP_HR (1 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_CASIO_TFT (2 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SAMSUNG_ALPHA (3 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_NONINTER_CCIR656 (4 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_INTER_CCIR656 (5 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SINGLE_CSTN (8 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SINGLE_MSTN (9 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_DUAL_CSTN (10 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_DUAL_MSTN (11 << LCD_DEV_MODE_BIT)
#define LCD_VSYNC_VPS_BIT 16
#define LCD_VSYNC_VPS_MASK (0xffff << LCD_VSYNC_VPS_BIT)
#define LCD_VSYNC_VPE_BIT 0
#define LCD_VSYNC_VPE_MASK (0xffff << LCD_VSYNC_VPS_BIT)
#define LCD_HSYNC_HPS_BIT 16
#define LCD_HSYNC_HPS_MASK (0xffff << LCD_HSYNC_HPS_BIT)
#define LCD_HSYNC_HPE_BIT 0
#define LCD_HSYNC_HPE_MASK (0xffff << LCD_HSYNC_HPE_BIT)
#define LCD_VAT_HT_BIT 16
#define LCD_VAT_HT_MASK (0xffff << LCD_VAT_HT_BIT)
#define LCD_VAT_VT_BIT 0
#define LCD_VAT_VT_MASK (0xffff << LCD_VAT_VT_BIT)
#define LCD_DAH_HDS_BIT 16
#define LCD_DAH_HDS_MASK (0xffff << LCD_DAH_HDS_BIT)
#define LCD_DAH_HDE_BIT 0
#define LCD_DAH_HDE_MASK (0xffff << LCD_DAH_HDE_BIT)
#define LCD_DAV_VDS_BIT 16
#define LCD_DAV_VDS_MASK (0xffff << LCD_DAV_VDS_BIT)
#define LCD_DAV_VDE_BIT 0
#define LCD_DAV_VDE_MASK (0xffff << LCD_DAV_VDE_BIT)
#define LCD_CTRL_BST_BIT 28
#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_RGB555 (1 << 27)
#define LCD_CTRL_OFUP (1 << 26)
#define LCD_CTRL_FRC_BIT 24
#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_PDD_BIT 16
#define LCD_CTRL_PDD_MASK (0xff << LCD_CTRL_PDD_BIT)
#define LCD_CTRL_EOFM (1 << 13)
#define LCD_CTRL_SOFM (1 << 12)
#define LCD_CTRL_OFUM (1 << 11)
#define LCD_CTRL_IFUM0 (1 << 10)
#define LCD_CTRL_IFUM1 (1 << 9)
#define LCD_CTRL_LDDM (1 << 8)
#define LCD_CTRL_QDM (1 << 7)
#define LCD_CTRL_BEDN (1 << 6)
#define LCD_CTRL_PEDN (1 << 5)
#define LCD_CTRL_DIS (1 << 4)
#define LCD_CTRL_ENA (1 << 3)
#define LCD_CTRL_BPP_BIT 0
#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT)
#define LCD_STATE_QD (1 << 7)
#define LCD_STATE_EOF (1 << 5)
#define LCD_STATE_SOF (1 << 4)
#define LCD_STATE_OFU (1 << 3)
#define LCD_STATE_IFU0 (1 << 2)
#define LCD_STATE_IFU1 (1 << 1)
#define LCD_STATE_LDD (1 << 0)
#define LCD_CMD_SOFINT (1 << 31)
#define LCD_CMD_EOFINT (1 << 30)
#define LCD_CMD_PAL (1 << 28)
#define LCD_CMD_LEN_BIT 0
#define LCD_CMD_LEN_MASK (0xffffff << LCD_CMD_LEN_BIT)
static void udelay (unsigned us):
for unsigned i = 0; i < us; ++i:
for unsigned k = 0; k < 100; ++k:
IE (2) &= ~SPEN
static void mdelay (unsigned ms):
udelay (1000 * ms)
static unsigned int get_pllout ():
unsigned plcr = CPM_PLCR1
if (plcr & CPM_PLCR1_PLL1EN)
unsigned nf, nr, no
unsigned od[4] = {1, 2, 2, 4}
nf = (plcr & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT
nr = (plcr & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT
no = od[((plcr & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)]
return (JZ_EXTAL) / ((nr+2) * no) * (nf+2)
else
return JZ_EXTAL
// level is in the range [0, 300]
static void set_backlight (unsigned level):
DUT = level
if level:
CTR = 0xbf
D (2) |= PWM_ENABLE
else:
CTR = 0x3f
D (2) &= ~PWM_ENABLE
// Write to a register. Value must be in range [0, 0xff].
static void write_reg (unsigned reg, unsigned value):
unsigned data = (reg << 0xa) | 0x200 | value
D (2) |= SPEN
D (2) = (D (2) & ~SPDA) | SPCK
D (2) &= ~SPEN
udelay(25)
for unsigned i = 0; i < 16; ++i:
D (2) &= ~SPCK
if data & 0x8000:
D (2) |= SPDA
else:
D (2) &= ~SPDA
udelay (25)
D (2) |= SPCK
udelay (25)
data <<= 1
D (2) |= SPEN
udelay(200)
static void lcd_enable ():
udelay (50)
D (2) &= ~LCD_RET
mdelay(150)
D (2) |= LCD_RET
mdelay(10)
// These values have been copied from the linux source.
// I have no idea what they do.
write_reg (0x00, 0x03)
write_reg (0x01, 0x40)
write_reg (0x02, 0x11)
write_reg (0x03, 0xcd)
write_reg (0x04, 0x32)
write_reg (0x05, 0x0e)
write_reg (0x07, 0x03)
write_reg (0x08, 0x08)
write_reg (0x09, 0x32)
write_reg (0x0A, 0x88)
write_reg (0x0B, 0xc6)
write_reg (0x0C, 0x20)
write_reg (0x0D, 0x20)
set_backlight (300)
static void lcd_disable ():
write_reg (0x00, 0x03)
set_backlight (0)
static void reset ():
// Use gpio pins as pwm.
AUR (2) = (AUR (2) & ~0x0fffffff) | 0x50000000
// Use gpio pins as lcd master.
ALR (1) = (ALR (1) & ~0x0000ffff) | 0x55550000
AUR (1) = 0x556a5555
// initialize things.
IE(2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
DI(2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
udelay (50)
D (2) &= ~LCD_RET
mdelay (150)
D (2) |= LCD_RET
mdelay (10)
lcd_enable ()
// For now, support only 16 bpp.
// Screen is 800x480 tft.
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
LCD_VSYNC = 20
LCD_HSYNC = 80
LCD_DAV = (20 << 16) | 500
LCD_DAH = (80 << 16) | 880
LCD_VAT = (880 << 16) | 500
LCD_CFG = MODE_TFT_GEN | PCLK_N | VSYNC_N
// Stop lcd.
CPM_MSCR |= 1 << 7
unsigned pclk = 60 * (800 * 3 + 80) * 500
unsigned pllout = get_pllout ()
CPM_CFCR2 = pllout / pclk - 1
unsigned v = pllout / (pclk * 4) - 1
while v < 0xf && pllout / (v + 1) > 150000000:
++v
CPM_CFCR = (CPM_CFCR & ~CPM_CFCR_LFR_MASK) | (v << CPM_CFCR_LFR_BIT) | CPM_CFCR_UPE
// Start lcd.
CPM_MSCR &= ~(1 << 7)
mdelay (1)
static void map_io (unsigned physical, unsigned address):
Capability page = memory_create_page (__my_memory)
alloc_physical (page, physical, 0)
memory_map (__my_memory, page, address, 1)
//drop (page)
int main ():
map_io (0x10010000, gpio_address)
map_io (0x10050000, pwm_address)
map_io (0x13050000, lcd_address)
map_io (0x10000000, cpm_address)
reset ()
while true:
Message msg
if !wait (&msg):
continue
switch msg.protected_data:
case LCD_BACKLIGHT:
set_backlight (c.data[0] > 300 ? 300 : c.data[0])
break
case LCD_RESET:
reset ()
break

View File

@ -1,23 +0,0 @@
#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// thread1.ccp: Testing userspace thread.
// 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 "iris.h"
int main ():
while true:
schedule ()

View File

@ -30,7 +30,6 @@ Capability *Memory::find_capability (unsigned code, bool *copy):
if p->data.frame == (unsigned)page: if p->data.frame == (unsigned)page:
return &page[num] return &page[num]
else: else:
code &= ~3
// Normal capability // Normal capability
for Capability *c = capabilities; c; c = c->next: for Capability *c = capabilities; c; c = c->next:
if c == (Capability *)code: if c == (Capability *)code:
@ -47,37 +46,36 @@ bool Receiver::try_deliver ():
break break
if !m: if !m:
return false return false
Capability::Context c Capability *c[4]
for unsigned i = 0; i < 4; ++i: for unsigned i = 0; i < 4; ++i:
c.data[i] = m->data[i]
if !m->capabilities[i]: if !m->capabilities[i]:
c.cap[i] = NULL c[i] = NULL
else: else:
c.cap[i] = owner->address_space->clone_capability (m->capabilities[i], true) c[i] = owner->address_space->clone_capability (m->capabilities[i], true)
if !c.cap[i]: if !c[i]:
for unsigned j = 0; j < i; ++j: for unsigned j = 0; j < i; ++j:
owner->address_space->free_capability (c.cap[i]) owner->address_space->free_capability (c[i])
return false return false
Thread_arch_receive (owner, &c) Thread_arch_receive (owner, m->data, c)
owner->unwait () owner->unwait ()
return true return true
bool Receiver::send_message (unsigned protected_data, Capability::Context *c): bool Receiver::send_message (unsigned protected_data, unsigned data[4], Capability *cap[4], bool copy[4]):
bool tried_direct = false bool tried_direct = false
if owner && owner->is_waiting () && (protected_data == reply_protected_data || !protected_only): if owner && owner->is_waiting () && (protected_data == reply_protected_data || !protected_only):
Capability::Context n Capability *c[4]
for unsigned i = 0; i < 4; ++i: for unsigned i = 0; i < 4; ++i:
if !c->cap[i]: if !cap[i]:
n.cap[i] = NULL c[i] = NULL
else: else:
n.cap[i] = owner->address_space->clone_capability (c->cap[i], c->copy[i]) c[i] = owner->address_space->clone_capability (cap[i], copy[i])
if !n.cap[i]: if !c[i]:
for unsigned j = 0; j < i; ++j: for unsigned j = 0; j < i; ++j:
owner->address_space->free_capability (n.cap[i]) owner->address_space->free_capability (c[i])
tried_direct = true tried_direct = true
break break
if !tried_direct: if !tried_direct:
Thread_arch_receive (owner, &n) Thread_arch_receive (owner, data, c)
owner->unwait () owner->unwait ()
return true return true
// The owner was not waiting, or it was not possible to deliver the message. Put it in the queue. // The owner was not waiting, or it was not possible to deliver the message. Put it in the queue.
@ -85,11 +83,11 @@ bool Receiver::send_message (unsigned protected_data, Capability::Context *c):
if !msg: if !msg:
return false return false
for unsigned i = 0; i < 4; ++i: for unsigned i = 0; i < 4; ++i:
msg->data[i] = c->data[i] msg->data[i] = data[i]
if !c->cap[i]: if !cap[i]:
msg->capabilities[i] = NULL msg->capabilities[i] = NULL
else: else:
msg->capabilities[i] = address_space->clone_capability (c->cap[i], c->copy[i]) msg->capabilities[i] = address_space->clone_capability (cap[i], copy[i])
if !msg->capabilities[i]: if !msg->capabilities[i]:
for unsigned j = 0; j < i; ++j: for unsigned j = 0; j < i; ++j:
address_space->free_capability (msg->capabilities[j]) address_space->free_capability (msg->capabilities[j])
@ -109,6 +107,8 @@ static void fill_cap (Capability *r, unsigned target, unsigned protected_data):
ref = &((Receiver *)target)->capabilities ref = &((Receiver *)target)->capabilities
else: else:
ref = &((Object_base *)protected_data)->refs ref = &((Object_base *)protected_data)->refs
// alloc_capability needs a Memory, but it isn't used if return storage is given.
ref = &((Object_base *)protected_data)->refs
// alloc_capability needs a Memory, but it isn't used if return storage is given. // alloc_capability needs a Memory, but it isn't used if return storage is given.
top_memory.alloc_capability ((Receiver *)target, NULL, ref, protected_data, r) top_memory.alloc_capability ((Receiver *)target, NULL, ref, protected_data, r)
@ -628,91 +628,52 @@ static void page_invoke (unsigned target, unsigned protected_data, Capability::C
if !p: if !p:
new_flags &= ~PAGE_FLAG_FRAME new_flags &= ~PAGE_FLAG_FRAME
// If we can get the new frame, get it. // If we can get the new frame, get it.
if new_flags & PAGE_FLAG_FRAME: Capability *c = &((Capability *)cappage->data.frame)[data[1]]
share_data->frame = raw_zalloc () c->invalidate ()
// clone_capability needs a Memory, but doesn't use it when storage is provided.
// If the frame is lost, the page is no longer shared. top_memory.clone_capability (cap, copy, c)
if old & ~new_flags & PAGE_FLAG_FRAME:
new_flags &= ~PAGE_FLAG_SHARED
if page:
if share_data->share_prev:
((Page *)share_data->share_prev)->data.share_next = share_data->share_next
if share_data->share_next:
((Page *)share_data->share_next)->data.share_prev = share_data->share_prev
else:
if share_data->share_prev:
((Cappage *)share_data->share_prev)->data.share_next = share_data->share_next
if share_data->share_next:
((Cappage *)share_data->share_next)->data.share_prev = share_data->share_prev
share_data->share_prev = NULL
share_data->share_next = NULL
// Set the shared flag.
if share_data->share_prev || share_data->share_next:
new_flags |= PAGE_FLAG_SHARED
// Don't allow making shared pages writable.
if ~old & PAGE_FLAG_WRITABLE:
new_flags &= ~PAGE_FLAG_WRITABLE
else:
new_flags &= ~PAGE_FLAG_SHARED
// Actually set the new flags.
share_data->flags = new_flags
// Update mappings if there is a change in writability, or in frame.
if page && ((share_data->flags ^ old) & PAGE_FLAG_WRITABLE || (share_data->flags ^ old) & PAGE_FLAG_FRAME):
Page_arch_update_mapping (page)
reply_num (share_data->flags)
break
case CAP_CAPPAGE_SET:
if !cappage || c->data[1] >= CAPPAGE_SIZE || !(target & CAP_PAGE_WRITE):
return
Capability *cap = &((Capability *)cappage->data.frame)[c->data[1]]
if cap:
cap->invalidate ()
// clone_capability needs a Memory, but doesn't use it when storage is provided.
top_memory.clone_capability (c->cap[0], c->copy[0], cap)
break break
default: default:
break break
static void capability_invoke (unsigned target, unsigned protected_data, Capability::Context *c): static void capability_invoke (unsigned target, unsigned protected_data, Capability *cap, unsigned request, unsigned data):
Capability *capability = (Capability *)protected_data Capability *capability = (Capability *)protected_data
switch c->data[0]: switch request:
case CAP_CAPABILITY_GET: case CAP_CAPABILITY_GET:
reply_cap (capability, true) reply_cap (capability, true)
break break
default: default:
break break
static bool kernel_invoke (unsigned target, unsigned protected_data, Capability::Context *c, Capability *self): static bool kernel_invoke (unsigned target, unsigned protected_data, unsigned d[4], Capability *c[4], bool copy[4], Capability *self):
// Kernel calling convention: // Kernel calling convention:
// data[0] is the request. // data[0] is the request.
// cap[0] is the reply capability // cap[0] is the reply capability
// other parameters' meanings depend on the operation. // other parameters' meanings depend on the operation.
if !((1 << d[0]) & target & ~REQUEST_MASK):
// You are not allowed to perform this operation.
return true
if (target & (CAPTYPE_MASK | (1 << CAP_RECEIVER_CALL))) == (CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_CALL)): if (target & (CAPTYPE_MASK | (1 << CAP_RECEIVER_CALL))) == (CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_CALL)):
// This is a call capability. // This is a call capability.
reply_receiver = (Receiver *)protected_data reply_receiver = (Receiver *)protected_data
reply_receiver->protected_only = !(target & (1 << CAP_RECEIVER_CALL_ASYNC)) reply_receiver->protected_only = !(target & (1 << CAP_RECEIVER_CALL_ASYNC))
Capability r Capability r
Capability *c0 = c->cap[0] Capability *c0 = c[0]
if (unsigned)c0->target & ~KERNEL_MASK: if ~(unsigned)c0->target & ~KERNEL_MASK:
// The call is not to a kernel capability.
fill_cap (&r, protected_data, reply_receiver->reply_protected_data) fill_cap (&r, protected_data, reply_receiver->reply_protected_data)
c->cap[0] = &r c[0] = &r
c->copy[0] = true copy[0] = true
bool ret = c0->target->send_message (c0->protected_data, c) bool ret = kernel_invoke ((unsigned)c0->target, c0->protected_data, d, c, copy, c0)
r.invalidate () r.invalidate ()
return ret return ret
else: else:
// Kernel call: don't create actual capablities. // Kernel call: don't create actual capablities.
reply = NULL reply = NULL
kernel_invoke ((unsigned)c0->target, c0->protected_data, c, c0) return kernel_invoke ((unsigned)c0->target, c0->protected_data, d, c, copy, c0)
return true
if (target & (CAPTYPE_MASK | (1 << CAP_RECEIVER_REPLY))) == (CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_REPLY)): if (target & (CAPTYPE_MASK | (1 << CAP_RECEIVER_REPLY))) == (CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_REPLY)):
// This is a reply capability. // This is a reply capability.
Receiver *r = (Receiver *)protected_data Receiver *r = (Receiver *)protected_data
r->send_message (r->reply_protected_data, c) r->send_message (r->reply_protected_data, d, c, copy)
while self->parent: while self->parent:
self = self->parent self = self->parent
while self->sibling_prev: while self->sibling_prev:
@ -721,42 +682,36 @@ static bool kernel_invoke (unsigned target, unsigned protected_data, Capability:
self->sibling_next->invalidate () self->sibling_next->invalidate ()
self->invalidate () self->invalidate ()
return true return true
// It's a normal kernel capability; check permission. reply = c[0]
if !((1 << c->data[0]) & target & REQUEST_MASK): if d[0] == CAP_DEGRADE:
// You are not allowed to perform this operation. reply_cap (target & d[1], protected_data)
dbg_send (c->data[0], 5)
schedule ()
return true
if c->data[0] == CAP_DEGRADE:
reply_cap (target & (CAPTYPE_MASK | (c->data[1] & REQUEST_MASK)), protected_data)
return true return true
switch target & CAPTYPE_MASK: switch target & CAPTYPE_MASK:
case CAPTYPE_RECEIVER: case CAPTYPE_RECEIVER:
receiver_invoke (target, protected_data, c) receiver_invoke (target, protected_data, c[1], d)
break break
case CAPTYPE_MEMORY: case CAPTYPE_MEMORY:
memory_invoke (target, protected_data, c) memory_invoke (target, protected_data, c[1], d[0], d[1])
break break
case CAPTYPE_THREAD: case CAPTYPE_THREAD:
thread_invoke (target, protected_data, c) thread_invoke (target, protected_data, c[1], d)
break break
case CAPTYPE_PAGE: case CAPTYPE_PAGE:
page_invoke (target, protected_data, c) page_invoke (target, protected_data, c[1], copy[1], d)
break break
case CAPTYPE_CAPABILITY: case CAPTYPE_CAPABILITY:
capability_invoke (target, protected_data, c) capability_invoke (target, protected_data, c[1], d[0], d[1])
break break
case CAPTYPE_CAPPAGE: case CAPTYPE_CAPPAGE:
page_invoke (target, protected_data, c[1], copy[1], d)
break break
default: default:
panic (0x99337744, "invalid capability type invoked") panic (0x99337744, "invalid capability type invoked")
return true return true
bool Capability::invoke (Context *c): bool Capability::invoke (unsigned data[4], Capability *cap[4], bool copy[4]):
if (unsigned)target & ~KERNEL_MASK: if (unsigned)target & ~KERNEL_MASK:
// This is not a kernel capability: send a message to the receiver. // This is not a kernel capability: send a message to the receiver.
return target->send_message (protected_data, c) return target->send_message (protected_data, data, cap, copy)
// This is a kernel capability. Use a function to allow optimized call capabilities. // This is a kernel capability. Use a function to allow optimized call capabilities.
reply = c->cap[0] return kernel_invoke ((unsigned)target, protected_data, data, cap, copy, this)
reply_receiver = NULL
return kernel_invoke ((unsigned)target, protected_data, c, this)

49
iris.h
View File

@ -138,6 +138,7 @@ typedef struct Message
{ {
unsigned data[4]; unsigned data[4];
Capability cap[4]; Capability cap[4];
unsigned protected_data; /* only used for receiving. */
} Message; } Message;
static int invoke (Capability target, Message *msg) static int invoke (Capability target, Message *msg)
@ -161,22 +162,26 @@ static int invoke (Capability target, Message *msg)
return ret; return ret;
} }
static void wait (Message *msg) static int wait (Message *msg)
{ {
int ret;
__asm__ volatile ("li $v0, 2\n" __asm__ volatile ("li $v0, 2\n"
"\tsyscall\n" "\tsyscall\n"
"\tlw $v1, %0\n" "\tsw $v0, %0\n"
"\tsw $t0, 0($v1)\n" "\tlw $v0, %1\n"
"\tsw $t1, 4($v1)\n" "\tsw $t0, 0($v0)\n"
"\tsw $t2, 8($v1)\n" "\tsw $t1, 4($v0)\n"
"\tsw $t3, 12($v1)\n" "\tsw $t2, 8($v0)\n"
"\tsw $a0, 16($v1)\n" "\tsw $t3, 12($v0)\n"
"\tsw $a1, 20($v1)\n" "\tsw $a0, 16($v0)\n"
"\tsw $a2, 24($v1)\n" "\tsw $a1, 20($v0)\n"
"\tsw $a3, 28($v1)" "\tsw $a2, 24($v0)\n"
: "\tsw $a3, 28($v0)\n"
"\tsw $v1, 32($v0)"
: "=m"(ret)
: "m"(msg) : "m"(msg)
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3"); : "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
return ret
} }
static int call (Capability target, Message *msg) static int call (Capability target, Message *msg)
@ -194,16 +199,18 @@ static int call (Capability target, Message *msg)
"\tlw $a2, 24($v1)\n" "\tlw $a2, 24($v1)\n"
"\tlw $a3, 28($v1)\n" "\tlw $a3, 28($v1)\n"
"\tsyscall\n" "\tsyscall\n"
"\tmove %0, $v0\n" "\tsw $v0, %0\n"
"\tsw $t0, 0($v1)\n" "\tlw $v0, %2\n"
"\tsw $t1, 4($v1)\n" "\tsw $t0, 0($v0)\n"
"\tsw $t2, 8($v1)\n" "\tsw $t1, 4($v0)\n"
"\tsw $t3, 12($v1)\n" "\tsw $t2, 8($v0)\n"
"\tsw $a0, 16($v1)\n" "\tsw $t3, 12($v0)\n"
"\tsw $a1, 20($v1)\n" "\tsw $a0, 16($v0)\n"
"\tsw $a2, 24($v1)\n" "\tsw $a1, 20($v0)\n"
"\tsw $a3, 28($v1)" "\tsw $a2, 24($v0)\n"
: "=r"(ret) "\tsw $a3, 28($v0)\n"
"\tsw $v1, 32($v0)"
: "=m"(ret)
: "m"(t), "m"(msg) : "m"(t), "m"(msg)
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3"); : "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
} }

View File

@ -28,7 +28,7 @@ arch_kernel_sources = mips/interrupts.cc mips/test.cc mips/arch.cc
boot_sources = mips/init.cc boot_sources = mips/init.cc
BUILT_SOURCES = $(kernel_sources) $(boot_sources) BUILT_SOURCES = $(kernel_sources) $(boot_sources)
arch_headers = mips/arch.hh arch_headers = mips/arch.hh
boot_threads = thread0 thread1 boot_threads = keyboard lcd
uimage: uimage:

View File

@ -54,6 +54,7 @@ void Thread_arch_receive (Thread *thread, Capability::Context *c):
thread->arch.t1 = c->data[1] thread->arch.t1 = c->data[1]
thread->arch.t2 = c->data[2] thread->arch.t2 = c->data[2]
thread->arch.t3 = c->data[3] thread->arch.t3 = c->data[3]
thread->arch.v1 = c->protected_data
thread->arch.v0 = 1 thread->arch.v0 = 1
void Thread_arch_receive_fail (Thread *thread): void Thread_arch_receive_fail (Thread *thread):